diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml new file mode 100644 index 0000000..c8f1e2f --- /dev/null +++ b/.github/workflows/workflow.yml @@ -0,0 +1,38 @@ +name: Run tests + +on: + push: + branches: + - master + - 'r&d' + pull_request: + branches: + - 'master' + workflow_dispatch: + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Start neo4j + run: docker compose up -d + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.9 + + - name: Install dependencies + run: | + pip install . + pip install pytest + + - name: Test + working-directory: tests + env: + NEO4J_HOST: localhost + run: python -m pytest diff --git a/.gitignore b/.gitignore index 0b8d97f..2c32167 100644 --- a/.gitignore +++ b/.gitignore @@ -51,3 +51,6 @@ docs/_build/ # Test log /testlog.log /venv_cpython/ +/scripts/merge-entities/target/ + +Cargo.lock \ No newline at end of file diff --git a/README.md b/README.md index fe313a7..fcd1844 100644 --- a/README.md +++ b/README.md @@ -1,230 +1,316 @@ Bitcoingraph - A Python library for exploring the Bitcoin transaction graph. -[![Build Status](https://travis-ci.org/behas/bitcoingraph.svg?branch=master)](https://travis-ci.org/behas/bitcoingraph) +## Difference with the "original" repository -## Prerequesites +The original repository was created in 2015 as a thesis for a university master degree. Since 2015, the +blockchain bitcoin has changed a lot. -### Bitcoin Core setup and configuration +In 2021, author [s7p](https://github.com/s7p) made a fork to add the difficulty, connect blocks together, +and fix some compatibility issues. -First, install the current version of Bitcoin Core (v.11.1), either from [source](https://github.com/bitcoin/bitcoin) or from a [pre-compiled executable](https://bitcoin.org/en/download). +This fork contains large refactorings. On the compatibility side, the addresses were not sent back in the +same format as they used to by bitcoind service (see https://github.com/btcsuite/btcd/issues/1874). +However, a much larger problem was the entity computation. The previous script was made in 2015, with the +entire blockchain weighting a few GBs. Nowadays, it weights close to 1TB. The script was not adapted to +this modern issue, and would require hundreds of GBs (we stopped testing after 200GB RAM, the exact number is unknown). -Once installed, you'll have access to three programs: `bitcoind` (= full peer), `bitcoin-qt` (= peer with GUI), and `bitcoin-cli` (RPC command line interface). The following instructions have been tested with `bitcoind` and assume you can start and run a Bitcoin Core peer as follows: +This required a complete overhaul of the entity computation. The script now contains arguments to limit the amount +of memory used, meaning you can probably run it on 16GB RAM (I wouldn't personally, but it will work). There's a section +below regarding requirements and giving more details. - bitcoind -printtoconsole -Second, you must make sure that your bitcoin client accepts JSON-RPC connections by modifying the [Bitcoin Core configuration file][bc_conf] as follows: +## Prerequisites - # server=1 tells Bitcoin-QT to accept JSON-RPC commands. - server=1 +### OS Note +The code can only be run on UNIX compatible systems, as it makes use of `sort` and `uniq` terminal commands. +The newer versions were only tested on linux, but the modifications made should not affect MAC OSX. +It was not tested on windows, it will not work on "native" windows, but could potentially work if run through +some linux virtualisation (e.g. WSL) or some UNIX terminal system. - # You must set rpcuser and rpcpassword to secure the JSON-RPC api - rpcuser=your_rpcuser - rpcpassword=your_rpcpass - - # How many seconds bitcoin will wait for a complete RPC HTTP request. - # after the HTTP connection is established. - rpctimeout=30 - - # Listen for RPC connections on this TCP port: - rpcport=8332 - - # Index non-wallet transactions (required for fast txn and block lookups) - txindex=1 - - # Enable unauthenticated REST API - rest= - -Test whether the JSON-RPC interface is working by starting your Bitcoin Core peer (...waiting until it finished startup...) and using the following cURL request (with adapted username and password): +### Mac OSX specifics - curl --data-binary '{"jsonrpc": "1.0", "id":"curltext", "method": "getblockchaininfo", "params": [] }' -H 'content-type: text/plain;' http://your_rpcuser:your_rpcpass@localhost:8332/ +Running bitcoingraph on a Mac requires coreutils to be installed + homebrew install coreutils -Third, since Bitcoingraph needs to access non-wallet blockchain transactions by their ids, you need to enable the transaction index in the Bitcoin Core database. This can be achieved by adding the following property to your `bitcoin.conf` +### Hardware - txindex=1 +The resources needed for creating the graph database are roughly proportional to the size of the database, up to some +limit. You could do testing and development with a tiny subset of all bitcoin transactions, e.g. the first 10000 blocks, +even on a Raspberry Pi. If you plan to import the entire blockchain, you will need much more serious hardware. -... and restarting your Bitcoin core peer as follows (rebuilding the index can take a while): +The basic requirements for a database up to July 2023 are: +- 4TB Disk Memory +- 48GB RAM +- A good CPU is nice to have as part of the pipeline uses it intesively +- If you're going to run your own bitcoin node, a good internet connection - bitcoind -reindex +A detailed explanation of the hardware requirements can be [found here](docs/documentation.md#hardware-requirements) +### Software -Test non-wallet transaction data access by taking an arbitrary transaction id and issuing the following request using cURL: +You will need neo4j >= 5.0 , python >= 3.9 with additional modules, PyPy, rust, and of course bitcoingraph. +If you do not have access to an RPC Bitcoin API, you will need to run your own Bitcoin node. +Please refer to the section in the appendix for instructions. - curl --data-binary '{"jsonrpc": "1.0", "id":"curltext", "method": "getrawtransaction", "params": ["110ed92f558a1e3a94976ddea5c32f030670b5c58c3cc4d857ac14d7a1547a90", 1] }' -H 'content-type: text/plain;' http://your_rpcuser:your_rpcpass@localhost:8332/ +#### Bitcoingraph library setup +Bitcoingraph is being developed in Python 3.9 Make sure it is running on your machine: -Finally, bitcoingraph also makes use of Bitcoin Core's HTTP REST interface, which is enabled using the following parameter: + python --version - bitcoind -rest +Download and unpack or git clone, test and install the Bitcoingraph library: -Test it using some sample block hash + cd bitcoingraph + pip install -r requirements.txt + py.test + python setup.py install - http://localhost:8332/rest/block/000000000000000e7ad69c72afc00dc4e05fc15ae3061c47d3591d07c09f2928.json +# What it creates +## Visualisation -When you reached this point, your Bitcoin Core setup is working. Terminate all running bitcoind instances and launch a new background daemon with enabled REST interface +![Visualisation](docs/graph.png) - bitcoind -daemon -rest +### Explanation: +- `Block`: a bitcoin block, with property `height`. Appends to the previous block to create the chain. -### Bitcoingraph library setup -Bitcoingraph is being developed in Python 3.4. Make sure it is running on your machine: +- `Transaction`: a bitcoin transaction, with property `txid` - python --version +- `Output`: Output created from a transaction, which is then used as input for a later transaction. Contains the + property `txid_n`, where `n` is the index of the output, and float `value` as the BTC value. A transaction `123` with + 2 outputs will create two nodes `123_0` and `123_1` both attached as in the outward direction -Now clone Bitcoingraph... + ```(:Transaction)-[:OUTPUT]->(:Output)``` - git clone https://github.com/behas/bitcoingraph.git + When these outputs are used as input in a later transaction, a new link will be added: + ```(:Transaction)-[:OUTPUT]->(:Output)-[:INPUT]->(newTransaction:Transaction)``` -...test and install the Bitcoingraph library: - cd bitcoingraph - pip install -r requirements.txt - py.test - python setup.py install +- `Address`: a bitcoin address, with property `address`. Old addresses using public keys are prefixed by `pk_`. The + latter also generate their P2PKH and P2WPKH addresses, which are connected through the + `(publicKey:Address)-[:GENERATES]->(p2pkh:Address)` relationship -### Mac OSX specifics +- `Entity`: an entity is an extra node which is not part of the blockchain. It is computed in post-processing and is + used to connect addresses that were used as input in the same transaction, basically making the assumption that it + implies they come from the same "Entity". Entities are merged together, meaning for example: + - Transaction `t1` receives inputs from addresses `a1`,`a2`,`a3` + - an entity is created connecting these addresses, `e1` + - Transaction `t2` receives inputs from addresses `a2`,`a4` + - since `a2` is already part of an entity, then `a4` is added to that same entity `e1` + - if `a4` was also already part of an entity, the two entities are merged into one -Running bitcoingraph on a Mac requires coreutils to be installed +## Boostrapping the underlying graph database (Neo4J) - homebrew install coreutils +bitcoingraph stores Bitcoin transactions as directed labelled graph in a Neo4J graph database instance. This database +can be bootstrapped by loading an initial blockchain dump, performing entity computation over the entire dump as +described by [Ron and Shamir](https://eprint.iacr.org/2012/584.pdf), and ingesting it into a running Neo4J instance. +#### Important note +When we took over this project, it had last been used on data from 2016. We had to entirely +re-write parts of the codebase due to the fact that the total bitcoin blockchain size at the time was +a couple of GBs, whereas nowadays, it's closer to 1TB. Many of the processes were not adapted for the size. -## Boostrapping the underlying graph database (Neo4J) - -bitcoingraph stores Bitcoin transactions as directed labelled graph in a Neo4J graph database instance. This database can be bootstrapped by loading an initial blockchain dump, performing entity computation over the entire dump as described by [Ron and Shamir](https://eprint.iacr.org/2012/584.pdf), and ingesting it into a running Neo4J instance. +I would strongly suggest anyone wanting to do this on the real blockchain, to first do the whole process +at small scale. Using only the first 200k blocks, the entire process can be done on any average modern laptop in less +than 2 hours (most of which will be waiting for computations). +This way, one can get comfortable with the process and try the database at small scale. At real scale, the process takes +a couple of days total in various computation, hence why it's better to do a trial run first. ### Step 1: Create transaction dump from blockchain -Bitcoingraph provides the `bcgraph-export` tool for exporting transactions in a given block range from the blockchain. The following command exports all transactions contained in block range 0 to 1000 using Neo4Js header format and separate CSV header files: +Bitcoingraph provides the `bcgraph-export` tool for exporting transactions in a given block range from the blockchain. +The following command exports all transactions contained in block range 0 to 1000 using Neo4Js header format and +separate CSV header files: bcgraph-export 0 1000 -u your_rpcuser -p your_rpcpass The following CSV files are created (with separate header files): -* addresses.csv: sorted list of Bitcoin addressed -* blocks.csv: list of blocks (hash, height, timestamp) -* transactions.csv: list of transactions (hash, coinbase/non-coinbase) -* outputs.csv: list of transaction outputs (output key, id, value, script type) -* rel_block_tx.csv: relationship between blocks and transactions (block_hash, tx_hash) -* rel_input.csv: relationship between transactions and transaction outputs (tx_hash, output key) -* rel_output_address.csv: relationship between outputs and addresses (output key, address) -* rel_tx_output.csv: relationship between transactions and transaction outputs (tx_hash, output key) +* **addresses.csv**: sorted list of Bitcoin addressed +* **blocks.csv**: list of blocks (hash, height, timestamp) +* **transactions.csv**: list of transactions (hash, coinbase/non-coinbase) +* **outputs.csv**: list of transaction outputs (output key, id, value, script type) +* **rel_block_tx.csv**: relationship between blocks and transactions (block_hash, tx_hash) +* **rel_input.csv**: relationship between transactions and transaction outputs (tx_hash, output key) +* **rel_output_address.csv**: relationship between outputs and addresses (output key, address) +* **rel_tx_output.csv**: relationship between transactions and transaction outputs (tx_hash, output key) +### Step 2: Compute entities over transaction dump +#### _and add connection between public keys and generated keys_ -### Step 2: Compute entities over transaction dump +#### 2.1: Compute the entities The following command computes entities for a given blockchain data dump: - bcgraph-compute-entities -i blocks_0_1000 + bcgraph-compute-entities -i blocks_0_1000 -Two additional files are created: -* entities.csv: list of entity identifiers (entity_id) -* rel_address_entity.csv: assignment of addresses to entities (address, entity_id) +This script is extremely computationally intensive, both in memory and in processing. +There are various parameters that can be tuned to optimize performance: +`--read-size`: Number of bytes to read at once from the file -### Step 3: Ingest pre-computed dump into Neo4J +`--chunk-size`: Size of a batch to process at once (in bytes) -Download and install [Neo4J][neo4j] community edition (>= 2.3.0): +`--cached-batches`: Number of last processed batches to keep in memory (uses a circular buffer) - tar xvfz neo4j-community-2.3.0-unix.tar.gz +`--max-queue-size`: Number of outputs to process together. This is the most important variable +both in terms of performance and memory usage. The higher, the better. -Test Neo4J installation: +On our machine with 110G and AMD Ryzen 5 5600G, we used the following parameters: +```commandline +--cached-batches 5_000 --chunk-size 50_000 --read-size 100_000_000 --max-queue-size 5_000_000_000 +``` +and reached max usage of 65G of RAM, and took ~15 hours to complete. - sudo neo4j start - http://localhost:7474/ +#### 2.2: Compute generated public keys +This step is optional, but allows to generate all the keys from the public keys. +The raw data doesn't include the connection between addresses in the format public key, and the +P2PKH and P2WPKH addresses that are "generated" by the latter. This script computes all the generated +addresses, and creates a file `rel_address_address.csv` and `rel_address_address_header.csv`. +It's essential to run this script at this step (and not earlier / later) since it also modifies `rel_entity_address.csv`, +allowing these generated keys to be connected through entity where needed. +``` +bcgraph-pk-to-addresses -i blocks_0_1000 +``` -Install and make sure is not running and pre-existing databases are removed: +#### 2.3: Merge the entities together - sudo neo4j stop - sudo rm -rf /var/lib/neo4j/data/* +Once the entities are computed, we also need to run the following +```bash +cd merge-entities && cargo run --release /path/to/rel_entity_address.csv /path/to/rel_entity_address_merged.csv +``` +The first generates computes entities, but due to the size of the file, it has to be +done in pieces. Therefore, if the entire entities happen to be over to pieces of the +file, it wrongly creates two entities. That's the reason for merge-entities script, +which is written in `rust` for performance purposes and merged all entities that +were separated back together. The second argument is the output file, in theory it can +be the same as the input, but what we used (and is used throughout this README) is simply +adding the \_merged suffix. -Switch back into the dump directory and create a new database using Neo4J's CSV importer tool: - - sudo neo4j-admin import \ - --nodes=:Block=blocks_header.csv,blocks.csv \ - --nodes=:Transaction=transactions_header.csv,transactions.csv \ - --nodes=:Output=outputs_header.csv,outputs.csv \ - --nodes=:Address=addresses_header.csv,addresses.csv \ - --nodes=:Entity=entities.csv \ - --relationships=CONTAINS=rel_block_tx_header.csv,rel_block_tx.csv \ - --relationships=APPENDS=rel_block_block_header.csv,rel_block_block.csv \ - --relationships=OUTPUT=rel_tx_output_header.csv,rel_tx_output.csv \ - --relationships=INPUT=rel_input_header.csv,rel_input.csv \ - --relationships=USES=rel_output_address_header.csv,rel_output_address.csv \ - --relationships=BELONGS_TO=rel_address_entity.csv - - -Then, start the Neo4J shell...: +Two additional files are created: - $NEO4J_HOME/bin/neo4j-shell -path $NEO4J_HOME/data +* entities.csv: list of entity identifiers (entity_id) +* rel_address_entity_merged.csv: assignment of addresses to entities (entity_id, address) -and create the following uniquness constraints: +#### Note: what is this about? +Check the [extended documentation](docs/documentations#entities-process) - CREATE CONSTRAINT ON (a:Address) ASSERT a.address IS UNIQUE; - CREATE CONSTRAINT ON (o:Output) ASSERT o.txid_n IS UNIQUE; +### Step 4: Ingest pre-computed dump into Neo4J +Install [Neo4J][neo4j] community edition (>= 5.0.0): -Finally start Neo4J +Get an rpm, deb or tar directly from [neo4j]https://neo4j.com/download-center/#community +or, preferably, install a [dnf]https://yum.neo4j.com/ or [apt]https://debian.neo4j.com/ +repo as appropriate for your distribution. The dnf/apt method has the additional advantage +of easy upgrades without the risk of accidentally overwriting your configuration files. - sudo neo4j start +Edit neo4j.conf as needed. If you plan to import the entire blockchain, you will probably +need to set +server.directories.data=/path/to/3TB/of/free/space/neo4j/data -### Step 4: Enrich transaction graph with identity information +The last two directories of the above path must be owned by the neo4j user. -Some bitcoin addresses have associated public identity information. Bitcoingraph provides an example script which collects information from blockchain.info. +Before you start neo4j for the first time, you can set an initial password with - utils/identity_information.py +`neo4j-admin dbms set-initial-password [--require-password-change]` -The resulting CSV file can be imported into Neo4j with the Cypher statement: +Test the Neo4J installation: - LOAD CSV WITH HEADERS FROM "file:///identities.csv" AS row - MERGE (a:Address {address: row.address}) - CREATE a-[:HAS]->(i:Identity - {name: row.tag, link: row.link, source: "https://blockchain.info/"}) + systemctl start neo4j + http://localhost:7474/ +Stop the database and remove any pre-existing databases: -### Step 5: Install Neo4J entity computation plugin + systemctl stop neo4j + sudo rm -rf /var/lib/neo4j/data/* -Clone the git repository and compile from source. This requires Maven and Java JDK to be installed. +Note: this will also delete your initial password. Set it again as needed. - git clone https://github.com/romankarl/entity-plugin.git - cd entity-plugin - mvn package +Switch back into the dump directory and create a new database using Neo4J's CSV importer tool: -Copy the JAR package into Neo4j's plugin directory. +```bash +neo4j-admin database import full --overwrite-destination \ + --nodes=:Block=blocks_header.csv,blocks.csv \ + --nodes=:Transaction=transactions_header.csv,transactions.csv \ + --nodes=:Output=outputs_header.csv,outputs.csv \ + --nodes=:Address=addresses_header.csv,addresses.csv \ + --relationships=CONTAINS=rel_block_tx_header.csv,rel_block_tx.csv \ + --relationships=APPENDS=rel_block_block_header.csv,rel_block_block.csv \ + --relationships=OUTPUT=rel_tx_output_header.csv,rel_tx_output.csv \ + --relationships=INPUT=rel_input_header.csv,rel_input.csv \ + --relationships=USES=rel_output_address_header.csv,rel_output_address.csv \ + --nodes=:Entity=entity_header.csv,entity.csv \ + --relationships=OWNER_OF=rel_entity_address_header.csv,rel_entity_address_merged.csv \ + --relationships=GENERATES=rel_address_address_header.csv,rel_address_address.csv \ + +``` +If you did the import as any user other than neo4j, `chown -R neo4j:neo4j /path/to/neo4j/data`. +Then, start neo4j and the Cypher shell...: + + `systemctl start neo4j` + `cypher-shell -u -p -d ` + +and create the following indexes: + +``` + // Allows fast queries using the address (highly recommended) + CREATE CONSTRAINT FOR (a:Address) REQUIRE a.address IS UNIQUE; + + // Allows fast queries using the block height (highly recommended) + CREATE CONSTRAINT FOR (b:Block) REQUIRE b.height IS UNIQUE; + + // Allows fast queries using the output txid_n (Optional) + CREATE CONSTRAINT FOR (o:Output) REQUIRE o.txid_n IS UNIQUE; - service neo4j-service stop - cp target/entities-plugin-0.0.1-SNAPSHOT.jar $NEO4J_HOME/plugins/ - service neo4j-service start + // Allows fast queries using transaction txid (Optional) + CREATE CONSTRAINT FOR (t:Transaction) REQUIRE t.txid IS UNIQUE; + + // Allows fast queries using entity_id (Optional) + CREATE CONSTRAINT FOR (e:Entity) REQUIRE e.entity_id IS UNIQUE; + + // Allows fast queries using entity name, only if you plan on naming entities. By default + // no names are present (Optional) + CREATE INDEX FOR (e:Entity) ON (e.name); +``` +Finally, start Neo4J + systemctl start neo4j -### Step 6: Enable synchronization with Bitcoin block chain +### Step 4: Enable synchronization with Bitcoin blockchain -Bitcoingraph provides a synchronisation script, which reads blocks from bitcoind and writes them into Neo4j. It is intended to be called by a cron job which runs daily or more frequent. For performance reasons it is no substitution for steps 1-3. +Bitcoingraph provides a synchronisation script, which reads blocks from bitcoind and writes them into Neo4j. It is +intended to be called by a cron job which runs daily or more frequent. For performance reasons it is no substitution for +steps 1-3. bcgraph-synchronize -s localhost -u RPC_USER -p RPC_PASS -S localhost -U NEO4J_USER -P NEO4J_PASS --rest - ## Contributors * [Bernhard Haslhofer](mailto:bernhard.haslhofer@ait.ac.at) * [Roman Karl](mailto:roman.karl@ait.ac.at) +* [Edoardo Barp](mailto:edoardo.barp@toptal.com) ## License -This library is release Open Source under the [MIT license](http://opensource.org/licenses/MIT). +This original library is released under the [MIT license](http://opensource.org/licenses/MIT). All changes on this fork +are released under [GPL 3 license](https://www.gnu.org/licenses/gpl-3.0.html) [bc_core]: https://github.com/bitcoin/bitcoin "Bitcoin Core" + [bc_conf]: https://en.bitcoin.it/wiki/Running_Bitcoin#Bitcoin.conf_Configuration_File "Bitcoin Core configuration file" + [neo4j]: http://neo4j.com/ "Neo4J" + diff --git a/assets/daily_values_unix.csv b/assets/daily_values_unix.csv new file mode 100644 index 0000000..3a1c922 --- /dev/null +++ b/assets/daily_values_unix.csv @@ -0,0 +1,5336 @@ +Date,Average,unixstart,unixend +2023-08-12,29447.980,1691798400,1691884799 +2023-08-11,29497.425,1691712000,1691798399 +2023-08-10,29643.005,1691625600,1691711999 +2023-08-09,29942.820,1691539200,1691625599 +2023-08-08,29670.550,1691452800,1691539199 +2023-08-07,29182.840,1691366400,1691452799 +2023-08-06,29132.495,1691280000,1691366399 +2023-08-05,29130.225,1691193600,1691279999 +2023-08-04,29262.700,1691107200,1691193599 +2023-08-03,29282.975,1691020800,1691107199 +2023-08-02,29875.025,1690934400,1691020799 +2023-08-01,29427.625,1690848000,1690934399 +2023-07-31,29390.980,1690761600,1690847999 +2023-07-30,29398.530,1690675200,1690761599 +2023-07-29,29351.250,1690588800,1690675199 +2023-07-28,29362.045,1690502400,1690588799 +2023-07-27,29446.855,1690416000,1690502399 +2023-07-26,29439.345,1690329600,1690415999 +2023-07-25,29253.830,1690243200,1690329599 +2023-07-24,30082.470,1690156800,1690243199 +2023-07-23,30038.155,1690070400,1690156799 +2023-07-22,29945.880,1689984000,1690070399 +2023-07-21,29916.610,1689897600,1689983999 +2023-07-20,30161.885,1689811200,1689897599 +2023-07-19,30025.615,1689724800,1689811199 +2023-07-18,30176.285,1689638400,1689724799 +2023-07-17,30263.145,1689552000,1689638399 +2023-07-16,30358.045,1689465600,1689551999 +2023-07-15,30331.390,1689379200,1689465599 +2023-07-14,31482.820,1689292800,1689379199 +2023-07-13,31047.060,1689206400,1689292799 +2023-07-12,30733.455,1689120000,1689206399 +2023-07-11,30577.300,1689033600,1689119999 +2023-07-10,30555.710,1688947200,1689033599 +2023-07-09,30331.425,1688860800,1688947199 +2023-07-08,30346.230,1688774400,1688860799 +2023-07-07,30118.520,1688688000,1688774399 +2023-07-06,30934.395,1688601600,1688687999 +2023-07-05,30830.280,1688515200,1688601599 +2023-07-04,31231.595,1688428800,1688515199 +2023-07-03,30978.750,1688342400,1688428799 +2023-07-02,30673.370,1688256000,1688342399 +2023-07-01,30563.795,1688169600,1688255999 +2023-06-30,30828.975,1688083200,1688169599 +2023-06-29,30433.075,1687996800,1688083199 +2023-06-28,30674.480,1687910400,1687996799 +2023-06-27,30612.635,1687824000,1687910399 +2023-06-26,30539.310,1687737600,1687823999 +2023-06-25,30784.510,1687651200,1687737599 +2023-06-24,30712.840,1687564800,1687651199 +2023-06-23,30655.495,1687478400,1687564799 +2023-06-22,30237.015,1687392000,1687478399 +2023-06-21,29468.155,1687305600,1687391999 +2023-06-20,27588.245,1687219200,1687305599 +2023-06-19,26659.625,1687132800,1687219199 +2023-06-18,26585.615,1687046400,1687132799 +2023-06-17,26550.885,1686960000,1687046399 +2023-06-16,25996.105,1686873600,1686959999 +2023-06-15,25402.810,1686787200,1686873599 +2023-06-14,25995.090,1686700800,1686787199 +2023-06-13,26105.060,1686614400,1686700799 +2023-06-12,26002.250,1686528000,1686614399 +2023-06-11,25984.035,1686441600,1686527999 +2023-06-10,26490.985,1686355200,1686441599 +2023-06-09,26637.830,1686268800,1686355199 +2023-06-08,26552.040,1686182400,1686268799 +2023-06-07,27260.970,1686096000,1686182399 +2023-06-06,26505.240,1686009600,1686095999 +2023-06-05,27107.785,1685923200,1686009599 +2023-06-04,27223.740,1685836800,1685923199 +2023-06-03,27266.050,1685750400,1685836799 +2023-06-02,27045.885,1685664000,1685750399 +2023-06-01,27276.225,1685577600,1685663999 +2023-05-31,27743.705,1685491200,1685577599 +2023-05-30,27887.740,1685404800,1685491199 +2023-05-29,28275.610,1685318400,1685404799 +2023-05-28,27503.360,1685232000,1685318399 +2023-05-27,26782.585,1685145600,1685231999 +2023-05-26,26690.135,1685059200,1685145599 +2023-05-25,26436.470,1684972800,1685059199 +2023-05-24,27222.410,1684886400,1684972799 +2023-05-23,27139.090,1684800000,1684886399 +2023-05-22,26892.785,1684713600,1684799999 +2023-05-21,27172.850,1684627200,1684713599 +2023-05-20,27014.110,1684540800,1684627199 +2023-05-19,26948.540,1684454400,1684540799 +2023-05-18,27427.845,1684368000,1684454399 +2023-05-17,27244.280,1684281600,1684367999 +2023-05-16,27223.910,1684195200,1684281599 +2023-05-15,27265.495,1684108800,1684195199 +2023-05-14,26961.125,1684022400,1684108799 +2023-05-13,26898.185,1683936000,1684022399 +2023-05-12,27004.395,1683849600,1683935999 +2023-05-11,27598.800,1683763200,1683849599 +2023-05-10,27958.265,1683676800,1683763199 +2023-05-09,27730.510,1683590400,1683676799 +2023-05-08,28518.045,1683504000,1683590399 +2023-05-07,28965.940,1683417600,1683503999 +2023-05-06,29642.985,1683331200,1683417599 +2023-05-05,29248.845,1683244800,1683331199 +2023-05-04,29170.475,1683158400,1683244799 +2023-05-03,28849.910,1683072000,1683158399 +2023-05-02,28441.770,1682985600,1683071999 +2023-05-01,29259.270,1682899200,1682985599 +2023-04-30,29557.975,1682812800,1682899199 +2023-04-29,29366.765,1682726400,1682812799 +2023-04-28,29513.685,1682640000,1682726399 +2023-04-27,29143.620,1682553600,1682639999 +2023-04-26,29131.650,1682467200,1682553599 +2023-04-25,27938.745,1682380800,1682467199 +2023-04-24,27778.390,1682294400,1682380799 +2023-04-23,27818.830,1682208000,1682294399 +2023-04-22,27558.055,1682121600,1682207999 +2023-04-21,28295.320,1682035200,1682121599 +2023-04-20,28929.345,1681948800,1682035199 +2023-04-19,30384.495,1681862400,1681948799 +2023-04-18,29941.360,1681776000,1681862399 +2023-04-17,30307.617,1681689600,1681775999 +2023-04-16,30411.141,1681603200,1681689599 +2023-04-15,30492.302,1681516800,1681603199 +2023-04-14,30668.291,1681430400,1681516799 +2023-04-13,30193.541,1681344000,1681430399 +2023-04-12,30317.315,1681257600,1681343999 +2023-04-11,30051.954,1681171200,1681257599 +2023-04-10,29028.406,1681084800,1681171199 +2023-04-09,28207.998,1680998400,1681084799 +2023-04-08,28027.078,1680912000,1680998399 +2023-04-07,28065.892,1680825600,1680911999 +2023-04-06,28174.107,1680739200,1680825599 +2023-04-05,28421.396,1680652800,1680739199 +2023-04-04,28106.584,1680566400,1680652799 +2023-04-03,28299.256,1680480000,1680566399 +2023-04-02,28484.342,1680393600,1680479999 +2023-04-01,28628.645,1680307200,1680393599 +2023-03-31,28321.261,1680220800,1680307199 +2023-03-30,28752.462,1680134400,1680220799 +2023-03-29,27926.336,1680048000,1680134399 +2023-03-28,27288.685,1679961600,1680047999 +2023-03-27,27993.557,1679875200,1679961599 +2023-03-26,27816.404,1679788800,1679875199 +2023-03-25,27599.150,1679702400,1679788799 +2023-03-24,28326.426,1679616000,1679702399 +2023-03-23,27940.583,1679529600,1679615999 +2023-03-22,28415.227,1679443200,1679529599 +2023-03-21,28061.790,1679356800,1679443199 +2023-03-20,28196.037,1679270400,1679356799 +2023-03-19,27615.454,1679184000,1679270399 +2023-03-18,27512.215,1679097600,1679183999 +2023-03-17,26354.341,1679011200,1679097599 +2023-03-16,24696.884,1678924800,1679011199 +2023-03-15,24860.742,1678838400,1678924799 +2023-03-14,25187.089,1678752000,1678838399 +2023-03-13,23169.564,1678665600,1678751999 +2023-03-12,21202.510,1678579200,1678665599 +2023-03-11,20393.099,1678492800,1678579199 +2023-03-10,20370.007,1678406400,1678492799 +2023-03-09,21753.386,1678320000,1678406399 +2023-03-08,22237.470,1678233600,1678319999 +2023-03-07,22451.794,1678147200,1678233599 +2023-03-06,22506.590,1678060800,1678147199 +2023-03-05,22478.209,1677974400,1678060799 +2023-03-04,22376.286,1677888000,1677974399 +2023-03-03,23466.676,1677801600,1677887999 +2023-03-02,23689.102,1677715200,1677801599 +2023-03-01,23497.417,1677628800,1677715199 +2023-02-28,23537.282,1677542400,1677628799 +2023-02-27,23716.540,1677456000,1677542399 +2023-02-26,23410.980,1677369600,1677455999 +2023-02-25,23195.472,1677283200,1677369599 +2023-02-24,24021.775,1677196800,1677283199 +2023-02-23,24386.159,1677110400,1677196799 +2023-02-22,24459.718,1677024000,1677110399 +2023-02-21,24969.958,1676937600,1677023999 +2023-02-20,24673.606,1676851200,1676937599 +2023-02-19,24874.176,1676764800,1676851199 +2023-02-18,24691.485,1676678400,1676764799 +2023-02-17,24264.365,1676592000,1676678399 +2023-02-16,24759.672,1676505600,1676591999 +2023-02-15,23263.560,1676419200,1676505599 +2023-02-14,22018.522,1676332800,1676419199 +2023-02-13,21834.522,1676246400,1676332799 +2023-02-12,21975.837,1676160000,1676246399 +2023-02-11,21762.387,1676073600,1676159999 +2023-02-10,21860.813,1675987200,1676073599 +2023-02-09,22972.933,1675900800,1675987199 +2023-02-08,23312.695,1675814400,1675900799 +2023-02-07,23039.492,1675728000,1675814399 +2023-02-06,23038.245,1675641600,1675727999 +2023-02-05,23375.851,1675555200,1675641599 +2023-02-04,23498.510,1675468800,1675555199 +2023-02-03,23577.406,1675382400,1675468799 +2023-02-02,23981.872,1675296000,1675382399 +2023-02-01,23449.170,1675209600,1675295999 +2023-01-31,23028.395,1675123200,1675209599 +2023-01-30,23768.055,1675036800,1675123199 +2023-01-29,23475.558,1674950400,1675036799 +2023-01-28,23125.824,1674864000,1674950399 +2023-01-27,23213.220,1674777600,1674863999 +2023-01-26,23158.862,1674691200,1674777599 +2023-01-25,23176.019,1674604800,1674691199 +2023-01-24,23034.264,1674518400,1674604799 +2023-01-23,22928.596,1674432000,1674518399 +2023-01-22,22914.998,1674345600,1674431999 +2023-01-21,22985.754,1674259200,1674345599 +2023-01-20,21881.151,1674172800,1674259199 +2023-01-19,20913.358,1674086400,1674172799 +2023-01-18,21343.196,1674000000,1674086399 +2023-01-17,21313.361,1673913600,1673999999 +2023-01-16,21142.556,1673827200,1673913599 +2023-01-15,20973.241,1673740800,1673827199 +2023-01-14,20535.782,1673654400,1673740799 +2023-01-13,19413.477,1673568000,1673654399 +2023-01-12,18486.143,1673481600,1673567999 +2023-01-11,17689.554,1673395200,1673481599 +2023-01-10,17333.498,1673308800,1673395199 +2023-01-09,17252.237,1673222400,1673308799 +2023-01-08,17007.168,1673136000,1673222399 +2023-01-07,16962.780,1673049600,1673135999 +2023-01-06,16918.308,1672963200,1673049599 +2023-01-05,16864.630,1672876800,1672963199 +2023-01-04,16823.945,1672790400,1672876799 +2023-01-03,16718.598,1672704000,1672790399 +2023-01-02,16687.890,1672617600,1672703999 +2023-01-01,16579.310,1672531200,1672617599 +2022-12-31,16620.485,1672444800,1672531199 +2022-12-30,16638.418,1672358400,1672444799 +2022-12-29,16601.303,1672272000,1672358399 +2022-12-28,16734.132,1672185600,1672271999 +2022-12-27,16941.413,1672099200,1672185599 +2022-12-26,16872.287,1672012800,1672099199 +2022-12-25,16842.942,1671926400,1672012799 +2022-12-24,16816.536,1671840000,1671926399 +2022-12-23,16861.561,1671753600,1671839999 +2022-12-22,16839.020,1671667200,1671753599 +2022-12-21,16911.204,1671580800,1671667199 +2022-12-20,16718.235,1671494400,1671580799 +2022-12-19,16771.134,1671408000,1671494399 +2022-12-18,16799.864,1671321600,1671407999 +2022-12-17,16711.181,1671235200,1671321599 +2022-12-16,17436.230,1671148800,1671235199 +2022-12-15,17818.981,1671062400,1671148799 +2022-12-14,18054.659,1670976000,1671062399 +2022-12-13,17567.480,1670889600,1670975999 +2022-12-12,17155.130,1670803200,1670889599 +2022-12-11,17191.527,1670716800,1670803199 +2022-12-10,17172.168,1670630400,1670716799 +2022-12-09,17249.432,1670544000,1670630399 +2022-12-08,17062.675,1670457600,1670543999 +2022-12-07,17093.100,1670371200,1670457599 +2022-12-06,17034.699,1670284800,1670371199 +2022-12-05,17252.032,1670198400,1670284799 +2022-12-04,17012.465,1670112000,1670198399 +2022-12-03,17107.492,1670025600,1670111999 +2022-12-02,17030.687,1669939200,1670025599 +2022-12-01,17189.869,1669852800,1669939199 +2022-11-30,16825.822,1669766400,1669852799 +2022-11-29,16368.184,1669680000,1669766399 +2022-11-28,16453.490,1669593600,1669679999 +2022-11-27,16525.356,1669507200,1669593599 +2022-11-26,16598.902,1669420800,1669507199 +2022-11-25,16609.376,1669334400,1669420799 +2022-11-24,16702.061,1669248000,1669334399 +2022-11-23,16436.940,1669161600,1669247999 +2022-11-22,16020.876,1669075200,1669161599 +2022-11-21,16286.806,1668988800,1669075199 +2022-11-20,16725.377,1668902400,1668988799 +2022-11-19,16755.840,1668816000,1668902399 +2022-11-18,16823.406,1668729600,1668815999 +2022-11-17,16699.526,1668643200,1668729599 +2022-11-16,16943.239,1668556800,1668643199 +2022-11-15,16850.489,1668470400,1668556799 +2022-11-14,16741.663,1668384000,1668470399 +2022-11-13,16867.284,1668297600,1668383999 +2022-11-12,17058.037,1668211200,1668297599 +2022-11-11,17633.941,1668124800,1668211199 +2022-11-10,17038.406,1668038400,1668124799 +2022-11-09,18555.939,1667952000,1668038399 +2022-11-08,20624.187,1667865600,1667951999 +2022-11-07,20980.521,1667779200,1667865599 +2022-11-06,21326.659,1667692800,1667779199 +2022-11-05,21303.354,1667606400,1667692799 +2022-11-04,20709.172,1667520000,1667606399 +2022-11-03,20263.766,1667433600,1667519999 +2022-11-02,20607.003,1667347200,1667433599 +2022-11-01,20573.072,1667260800,1667347199 +2022-10-31,20713.847,1667174400,1667260799 +2022-10-30,20859.953,1667088000,1667174399 +2022-10-29,20799.468,1667001600,1667087999 +2022-10-28,20513.179,1666915200,1667001599 +2022-10-27,20813.782,1666828800,1666915199 +2022-10-26,20512.453,1666742400,1666828799 +2022-10-25,19859.343,1666656000,1666742399 +2022-10-24,19571.447,1666569600,1666655999 +2022-10-23,19436.653,1666483200,1666569599 +2022-10-22,19205.551,1666396800,1666483199 +2022-10-21,19136.969,1666310400,1666396799 +2022-10-20,19225.815,1666224000,1666310399 +2022-10-19,19333.128,1666137600,1666223999 +2022-10-18,19615.745,1666051200,1666137599 +2022-10-17,19453.582,1665964800,1666051199 +2022-10-16,19231.822,1665878400,1665964799 +2022-10-15,19200.906,1665792000,1665878399 +2022-10-14,19635.991,1665705600,1665791999 +2022-10-13,19304.855,1665619200,1665705599 +2022-10-12,19133.378,1665532800,1665619199 +2022-10-11,19194.729,1665446400,1665532799 +2022-10-10,19479.570,1665360000,1665446399 +2022-10-09,19477.333,1665273600,1665359999 +2022-10-08,19570.576,1665187200,1665273599 +2022-10-07,19999.510,1665100800,1665187199 +2022-10-06,20284.626,1665014400,1665100799 +2022-10-05,20341.541,1664928000,1665014399 +2022-10-04,19997.419,1664841600,1664927999 +2022-10-03,19362.010,1664755200,1664841599 +2022-10-02,19349.991,1664668800,1664755199 +2022-10-01,19447.156,1664582400,1664668799 +2022-09-30,19862.774,1664496000,1664582399 +2022-09-29,19506.071,1664409600,1664495999 +2022-09-28,19420.879,1664323200,1664409599 +2022-09-27,19785.460,1664236800,1664323199 +2022-09-26,19040.106,1664150400,1664236799 +2022-09-25,19029.564,1664064000,1664150399 +2022-09-24,19292.454,1663977600,1664063999 +2022-09-23,19435.722,1663891200,1663977599 +2022-09-22,18987.181,1663804800,1663891199 +2022-09-21,19272.387,1663718400,1663804799 +2022-09-20,19580.724,1663632000,1663718399 +2022-09-19,19521.841,1663545600,1663631999 +2022-09-18,20121.849,1663459200,1663545599 +2022-09-17,19988.533,1663372800,1663459199 +2022-09-16,19791.284,1663286400,1663372799 +2022-09-15,20255.244,1663200000,1663286399 +2022-09-14,20330.893,1663113600,1663199999 +2022-09-13,22549.375,1663027200,1663113599 +2022-09-12,22138.618,1662940800,1663027199 +2022-09-11,21729.195,1662854400,1662940799 +2022-09-10,21565.222,1662768000,1662854399 +2022-09-09,20360.600,1662681600,1662767999 +2022-09-08,19356.010,1662595200,1662681599 +2022-09-07,19116.247,1662508800,1662595199 +2022-09-06,19970.505,1662422400,1662508799 +2022-09-05,20020.476,1662336000,1662422399 +2022-09-04,19915.202,1662249600,1662335999 +2022-09-03,20002.060,1662163200,1662249599 +2022-09-02,20266.524,1662076800,1662163199 +2022-09-01,20119.736,1661990400,1662076799 +2022-08-31,20116.135,1661904000,1661990399 +2022-08-30,20426.534,1661817600,1661903999 +2022-08-29,19950.141,1661731200,1661817599 +2022-08-28,20083.043,1661644800,1661731199 +2022-08-27,20293.184,1661558400,1661644799 +2022-08-26,21687.991,1661472000,1661558399 +2022-08-25,21570.437,1661385600,1661471999 +2022-08-24,21669.661,1661299200,1661385599 +2022-08-23,21522.812,1661212800,1661299199 +2022-08-22,21511.405,1661126400,1661212799 +2022-08-21,21404.610,1661040000,1661126399 +2022-08-20,21086.750,1660953600,1661039999 +2022-08-19,23192.072,1660867200,1660953599 +2022-08-18,23457.002,1660780800,1660867199 +2022-08-17,24137.729,1660694400,1660780799 +2022-08-16,24162.582,1660608000,1660694399 +2022-08-15,24718.480,1660521600,1660607999 +2022-08-14,24709.281,1660435200,1660521599 +2022-08-13,24639.581,1660348800,1660435199 +2022-08-12,24175.983,1660262400,1660348799 +2022-08-11,24397.429,1660176000,1660262399 +2022-08-10,23647.511,1660089600,1660175999 +2022-08-09,23855.197,1660003200,1660089599 +2022-08-08,23698.728,1659916800,1660003199 +2022-08-07,23156.369,1659830400,1659916799 +2022-08-06,23311.556,1659744000,1659830399 +2022-08-05,23021.708,1659657600,1659743999 +2022-08-04,23008.927,1659571200,1659657599 +2022-08-03,23277.265,1659484800,1659571199 +2022-08-02,23352.656,1659398400,1659484799 +2022-08-01,23393.575,1659312000,1659398399 +2022-07-31,23901.394,1659225600,1659311999 +2022-07-30,24189.452,1659139200,1659225599 +2022-07-29,24075.330,1659052800,1659139199 +2022-07-28,23547.237,1658966400,1659052799 +2022-07-27,22111.371,1658880000,1658966399 +2022-07-26,21317.184,1658793600,1658879999 +2022-07-25,22602.435,1658707200,1658793599 +2022-07-24,22724.715,1658620800,1658707199 +2022-07-23,22827.314,1658534400,1658620799 +2022-07-22,23416.277,1658448000,1658534399 +2022-07-21,23311.210,1658361600,1658447999 +2022-07-20,23823.817,1658275200,1658361599 +2022-07-19,23106.435,1658188800,1658275199 +2022-07-18,21738.047,1658102400,1658188799 +2022-07-17,21406.860,1658016000,1658102399 +2022-07-16,21166.563,1657929600,1658015999 +2022-07-15,20874.468,1657843200,1657929599 +2022-07-14,20494.869,1657756800,1657843199 +2022-07-13,19776.522,1657670400,1657756799 +2022-07-12,20002.373,1657584000,1657670399 +2022-07-11,20849.272,1657497600,1657583999 +2022-07-10,21587.202,1657411200,1657497599 +2022-07-09,21772.711,1657324800,1657411199 +2022-07-08,21993.465,1657238400,1657324799 +2022-07-07,21181.819,1657152000,1657238399 +2022-07-06,20412.860,1657065600,1657151999 +2022-07-05,20453.708,1656979200,1657065599 +2022-07-04,19806.813,1656892800,1656979199 +2022-07-03,19408.228,1656806400,1656892799 +2022-07-02,19346.072,1656720000,1656806399 +2022-07-01,20272.986,1656633600,1656719999 +2022-06-30,20131.955,1656547200,1656633599 +2022-06-29,20334.136,1656460800,1656547199 +2022-06-28,20949.411,1656374400,1656460799 +2022-06-27,21266.636,1656288000,1656374399 +2022-06-26,21670.672,1656201600,1656287999 +2022-06-25,21374.974,1656115200,1656201599 +2022-06-24,21279.515,1656028800,1656115199 +2022-06-23,20567.916,1655942400,1656028799 +2022-06-22,20791.042,1655856000,1655942399 +2022-06-21,21112.339,1655769600,1655855999 +2022-06-20,20747.313,1655683200,1655769599 +2022-06-19,19858.396,1655596800,1655683199 +2022-06-18,20601.831,1655510400,1655596799 +2022-06-17,20849.104,1655424000,1655510399 +2022-06-16,22761.239,1655337600,1655423999 +2022-06-15,22414.079,1655251200,1655337599 +2022-06-14,22719.557,1655164800,1655251199 +2022-06-13,26731.647,1655078400,1655164799 +2022-06-12,28467.642,1654992000,1655078399 +2022-06-11,29260.560,1654905600,1654991999 +2022-06-10,30195.287,1654819200,1654905599 +2022-06-09,30426.406,1654732800,1654819199 +2022-06-08,31194.439,1654646400,1654732799 +2022-06-07,31463.009,1654560000,1654646399 +2022-06-06,30829.928,1654473600,1654559999 +2022-06-05,30004.711,1654387200,1654473599 +2022-06-04,29816.800,1654300800,1654387199 +2022-06-03,30555.314,1654214400,1654300799 +2022-06-02,30204.648,1654128000,1654214399 +2022-06-01,31862.729,1654041600,1654127999 +2022-05-31,32016.310,1653955200,1654041599 +2022-05-30,30675.364,1653868800,1653955199 +2022-05-29,29280.865,1653782400,1653868799 +2022-05-28,28875.285,1653696000,1653782399 +2022-05-27,29276.288,1653609600,1653695999 +2022-05-26,29711.682,1653523200,1653609599 +2022-05-25,29928.014,1653436800,1653523199 +2022-05-24,29445.402,1653350400,1653436799 +2022-05-23,30457.927,1653264000,1653350399 +2022-05-22,29935.970,1653177600,1653263999 +2022-05-21,29399.431,1653091200,1653177599 +2022-05-20,30508.987,1653004800,1653091199 +2022-05-19,29596.337,1652918400,1653004799 +2022-05-18,30534.506,1652832000,1652918399 +2022-05-17,30282.379,1652745600,1652831999 +2022-05-16,31293.222,1652659200,1652745599 +2022-05-15,30733.706,1652572800,1652659199 +2022-05-14,29772.795,1652486400,1652572799 +2022-05-13,30001.371,1652400000,1652486399 +2022-05-12,29588.738,1652313600,1652399999 +2022-05-11,31519.786,1652227200,1652313599 +2022-05-10,31340.487,1652140800,1652227199 +2022-05-09,34139.317,1652054400,1652140799 +2022-05-08,35487.350,1651968000,1652054399 +2022-05-07,36070.694,1651881600,1651967999 +2022-05-06,36576.633,1651795200,1651881599 +2022-05-05,39741.975,1651708800,1651795199 +2022-05-04,38824.625,1651622400,1651708799 +2022-05-03,38575.872,1651536000,1651622399 +2022-05-02,38769.451,1651449600,1651535999 +2022-05-01,38125.810,1651363200,1651449599 +2022-04-30,38683.805,1651276800,1651363199 +2022-04-29,39828.291,1651190400,1651276799 +2022-04-28,39771.359,1651104000,1651190399 +2022-04-27,38739.963,1651017600,1651103999 +2022-04-26,40562.334,1650931200,1651017599 +2022-04-25,40016.444,1650844800,1650931199 +2022-04-24,39643.835,1650758400,1650844799 +2022-04-23,39822.229,1650672000,1650758399 +2022-04-22,40619.710,1650585600,1650671999 +2022-04-21,42147.288,1650499200,1650585599 +2022-04-20,41811.972,1650412800,1650499199 +2022-04-19,41216.777,1650326400,1650412799 +2022-04-18,40359.306,1650240000,1650326399 +2022-04-17,40469.911,1650153600,1650239999 +2022-04-16,40600.140,1650067200,1650153599 +2022-04-15,40265.019,1649980800,1650067199 +2022-04-14,41312.268,1649894400,1649980799 +2022-04-13,40726.264,1649808000,1649894399 +2022-04-12,40069.759,1649721600,1649807999 +2022-04-11,42273.105,1649635200,1649721599 +2022-04-10,43070.670,1649548800,1649635199 +2022-04-09,42520.136,1649462400,1649548799 +2022-04-08,43678.342,1649376000,1649462399 +2022-04-07,43505.069,1649289600,1649375999 +2022-04-06,45479.969,1649203200,1649289599 +2022-04-05,46870.951,1649116800,1649203199 +2022-04-04,46641.492,1649030400,1649116799 +2022-04-03,46562.742,1648944000,1649030399 +2022-04-02,46637.673,1648857600,1648943999 +2022-04-01,46064.436,1648771200,1648857599 +2022-03-31,47307.989,1648684800,1648771199 +2022-03-30,47564.481,1648598400,1648684799 +2022-03-29,47537.370,1648512000,1648598399 +2022-03-28,47477.290,1648425600,1648511999 +2022-03-27,45687.427,1648339200,1648425599 +2022-03-26,44542.150,1648252800,1648339199 +2022-03-25,44526.171,1648166400,1648252799 +2022-03-24,43549.085,1648080000,1648166399 +2022-03-23,42644.001,1647993600,1648079999 +2022-03-22,42120.733,1647907200,1647993599 +2022-03-21,41359.065,1647820800,1647907199 +2022-03-20,42243.755,1647734400,1647820799 +2022-03-19,42054.777,1647648000,1647734399 +2022-03-18,41572.340,1647561600,1647647999 +2022-03-17,41211.088,1647475200,1647561599 +2022-03-16,40419.890,1647388800,1647475199 +2022-03-15,39737.209,1647302400,1647388799 +2022-03-14,38796.524,1647216000,1647302399 +2022-03-13,39012.465,1647129600,1647215999 +2022-03-12,39025.222,1647043200,1647129599 +2022-03-11,39773.308,1646956800,1647043199 +2022-03-10,41976.312,1646870400,1646956799 +2022-03-09,40624.961,1646784000,1646870399 +2022-03-08,38677.438,1646697600,1646783999 +2022-03-07,38899.452,1646611200,1646697599 +2022-03-06,39518.092,1646524800,1646611199 +2022-03-05,39360.627,1646438400,1646524799 +2022-03-04,42481.761,1646352000,1646438399 +2022-03-03,43968.603,1646265600,1646351999 +2022-03-02,44789.249,1646179200,1646265599 +2022-03-01,43985.040,1646092800,1646179199 +2022-02-28,40710.172,1646006400,1646092799 +2022-02-27,39432.604,1645920000,1646006399 +2022-02-26,39598.476,1645833600,1645919999 +2022-02-25,38973.169,1645747200,1645833599 +2022-02-24,38174.594,1645660800,1645747199 +2022-02-23,38693.059,1645574400,1645660799 +2022-02-22,37698.916,1645488000,1645574399 +2022-02-21,38882.523,1645401600,1645487999 +2022-02-20,40098.022,1645315200,1645401599 +2022-02-19,40209.190,1645228800,1645315199 +2022-02-18,40726.111,1645142400,1645228799 +2022-02-17,43987.786,1645056000,1645142399 +2022-02-16,44522.959,1644969600,1645055999 +2022-02-15,43625.801,1644883200,1644969599 +2022-02-14,42408.219,1644796800,1644883199 +2022-02-13,42447.896,1644710400,1644796799 +2022-02-12,42669.197,1644624000,1644710399 +2022-02-11,43703.389,1644537600,1644623999 +2022-02-10,45012.553,1644451200,1644537599 +2022-02-09,44383.004,1644364800,1644451199 +2022-02-08,44621.156,1644278400,1644364799 +2022-02-07,43429.293,1644192000,1644278399 +2022-02-06,41957.045,1644105600,1644191999 +2022-02-05,41713.387,1644019200,1644105599 +2022-02-04,39468.148,1643932800,1644019199 +2022-02-03,36988.428,1643846400,1643932799 +2022-02-02,38754.357,1643760000,1643846399 +2022-02-01,38837.712,1643673600,1643759999 +2022-01-31,38291.249,1643587200,1643673599 +2022-01-30,38224.842,1643500800,1643587199 +2022-01-29,38159.962,1643414400,1643500799 +2022-01-28,37496.455,1643328000,1643414399 +2022-01-27,36994.268,1643241600,1643327999 +2022-01-26,37920.332,1643155200,1643241599 +2022-01-25,37035.934,1643068800,1643155199 +2022-01-24,36725.214,1642982400,1643068799 +2022-01-23,35728.124,1642896000,1642982399 +2022-01-22,36571.355,1642809600,1642895999 +2022-01-21,40886.169,1642723200,1642809599 +2022-01-20,42570.522,1642636800,1642723199 +2022-01-19,42423.011,1642550400,1642636799 +2022-01-18,42405.977,1642464000,1642550399 +2022-01-17,43096.167,1642377600,1642463999 +2022-01-16,43260.968,1642291200,1642377599 +2022-01-15,43394.564,1642204800,1642291199 +2022-01-14,42968.849,1642118400,1642204799 +2022-01-13,44089.443,1642032000,1642118399 +2022-01-12,43439.488,1641945600,1642031999 +2022-01-11,42442.822,1641859200,1641945599 +2022-01-10,42029.759,1641772800,1641859199 +2022-01-09,42186.845,1641686400,1641772799 +2022-01-08,41920.820,1641600000,1641686399 +2022-01-07,43136.994,1641513600,1641599999 +2022-01-06,43568.429,1641427200,1641513599 +2022-01-05,46420.781,1641340800,1641427199 +2022-01-04,46953.036,1641254400,1641340799 +2022-01-03,47413.153,1641168000,1641254399 +2022-01-02,47796.025,1641081600,1641167999 +2022-01-01,47019.257,1640995200,1641081599 +2021-12-31,47822.679,1640908800,1640995199 +2021-12-30,47153.487,1640822400,1640908799 +2021-12-29,47829.943,1640736000,1640822399 +2021-12-28,50667.988,1640649600,1640735999 +2021-12-27,51369.088,1640563200,1640649599 +2021-12-26,50799.926,1640476800,1640563199 +2021-12-25,50933.388,1640390400,1640476799 +2021-12-24,51272.798,1640304000,1640390399 +2021-12-23,49967.524,1640217600,1640303999 +2021-12-22,49215.468,1640131200,1640217599 +2021-12-21,48087.573,1640044800,1640131199 +2021-12-20,47006.896,1639958400,1640044799 +2021-12-19,47389.119,1639872000,1639958399 +2021-12-18,46703.891,1639785600,1639871999 +2021-12-17,47805.386,1639699200,1639785599 +2021-12-16,49072.612,1639612800,1639699199 +2021-12-15,48909.507,1639526400,1639612799 +2021-12-14,47642.692,1639440000,1639526399 +2021-12-13,50118.283,1639353600,1639439999 +2021-12-12,49968.002,1639267200,1639353599 +2021-12-11,48290.030,1639180800,1639267199 +2021-12-10,48788.354,1639094400,1639180799 +2021-12-09,50601.888,1639008000,1639094399 +2021-12-08,50814.505,1638921600,1639007999 +2021-12-07,51209.459,1638835200,1638921599 +2021-12-06,50118.363,1638748800,1638835199 +2021-12-05,49426.959,1638662400,1638748799 +2021-12-04,53670.905,1638576000,1638662399 +2021-12-03,56929.350,1638489600,1638575999 +2021-12-02,57269.353,1638403200,1638489599 +2021-12-01,57964.409,1638316800,1638403199 +2021-11-30,58381.208,1638230400,1638316799 +2021-11-29,57993.915,1638144000,1638230399 +2021-11-28,56067.142,1638057600,1638143999 +2021-11-27,54381.518,1637971200,1638057599 +2021-11-26,59016.804,1637884800,1637971199 +2021-11-25,58263.014,1637798400,1637884799 +2021-11-24,57612.495,1637712000,1637798399 +2021-11-23,57044.858,1637625600,1637711999 +2021-11-22,58886.454,1637539200,1637625599 +2021-11-21,59757.368,1637452800,1637539199 +2021-11-20,58942.059,1637366400,1637452799 +2021-11-19,57624.634,1637280000,1637366399 +2021-11-18,60605.154,1637193600,1637279999 +2021-11-17,60422.345,1637107200,1637193599 +2021-11-16,63609.998,1637020800,1637107199 +2021-11-15,65881.474,1636934400,1637020799 +2021-11-14,64820.115,1636848000,1636934399 +2021-11-13,64511.852,1636761600,1636847999 +2021-11-12,65077.113,1636675200,1636761599 +2021-11-11,65256.574,1636588800,1636675199 +2021-11-10,67849.703,1636502400,1636588799 +2021-11-09,67993.670,1636416000,1636502399 +2021-11-08,65474.101,1636329600,1636415999 +2021-11-07,62317.093,1636243200,1636329599 +2021-11-06,61242.057,1636156800,1636243199 +2021-11-05,61949.617,1636070400,1636156799 +2021-11-04,62977.504,1635984000,1636070399 +2021-11-03,63306.491,1635897600,1635983999 +2021-11-02,62504.958,1635811200,1635897599 +2021-11-01,61829.170,1635724800,1635811199 +2021-10-31,62117.509,1635638400,1635724799 +2021-10-30,62225.013,1635552000,1635638399 +2021-10-29,61772.550,1635465600,1635551999 +2021-10-28,60189.044,1635379200,1635465599 +2021-10-27,60888.578,1635292800,1635379199 +2021-10-26,63171.667,1635206400,1635292799 +2021-10-25,62283.285,1635120000,1635206399 +2021-10-24,61370.014,1635033600,1635119999 +2021-10-23,61207.089,1634947200,1635033599 +2021-10-22,62926.665,1634860800,1634947199 +2021-10-21,66283.309,1634774400,1634860799 +2021-10-20,65591.909,1634688000,1634774399 +2021-10-19,63224.492,1634601600,1634687999 +2021-10-18,62045.637,1634515200,1634601599 +2021-10-17,61225.073,1634428800,1634515199 +2021-10-16,62018.698,1634342400,1634428799 +2021-10-15,59937.701,1634256000,1634342399 +2021-10-14,57889.206,1634169600,1634255999 +2021-10-13,56858.406,1634083200,1634169599 +2021-10-12,57477.964,1633996800,1634083199 +2021-10-11,56216.219,1633910400,1633996799 +2021-10-10,55569.069,1633824000,1633910399 +2021-10-09,54674.127,1633737600,1633823999 +2021-10-08,54863.756,1633651200,1633737599 +2021-10-07,55315.911,1633564800,1633651199 +2021-10-06,53528.430,1633478400,1633564799 +2021-10-05,50529.513,1633392000,1633478399 +2021-10-04,48806.214,1633305600,1633391999 +2021-10-03,48418.885,1633219200,1633305599 +2021-10-02,48197.755,1633132800,1633219199 +2021-10-01,46077.870,1633046400,1633132799 +2021-09-30,42784.444,1632960000,1633046399 +2021-09-29,41784.794,1632873600,1632959999 +2021-09-28,42421.929,1632787200,1632873599 +2021-09-27,43721.436,1632700800,1632787199 +2021-09-26,43205.190,1632614400,1632700799 +2021-09-25,42883.857,1632528000,1632614399 +2021-09-24,44948.156,1632441600,1632527999 +2021-09-23,44222.069,1632355200,1632441599 +2021-09-22,42323.708,1632268800,1632355199 +2021-09-21,43178.710,1632182400,1632268799 +2021-09-20,47236.509,1632096000,1632182399 +2021-09-19,48330.018,1632009600,1632095999 +2021-09-18,48014.826,1631923200,1632009599 +2021-09-17,47945.144,1631836800,1631923199 +2021-09-16,48297.955,1631750400,1631836799 +2021-09-15,47737.582,1631664000,1631750399 +2021-09-14,46053.045,1631577600,1631663999 +2021-09-13,46153.702,1631491200,1631577599 +2021-09-12,45759.216,1631404800,1631491199 +2021-09-11,45381.089,1631318400,1631404799 +2021-09-10,46699.707,1631232000,1631318399 +2021-09-09,46632.913,1631145600,1631231999 +2021-09-08,47030.589,1631059200,1631145599 +2021-09-07,52770.154,1630972800,1631059199 +2021-09-06,52227.202,1630886400,1630972799 +2021-09-05,50873.847,1630800000,1630886399 +2021-09-04,50263.660,1630713600,1630799999 +2021-09-03,50144.939,1630627200,1630713599 +2021-09-02,49572.771,1630540800,1630627199 +2021-09-01,48030.788,1630454400,1630540799 +2021-08-31,47522.411,1630368000,1630454399 +2021-08-30,48792.874,1630281600,1630367999 +2021-08-29,49214.867,1630195200,1630281599 +2021-08-28,49148.938,1630108800,1630195199 +2021-08-27,47957.338,1630022400,1630108799 +2021-08-26,49157.549,1629936000,1630022399 +2021-08-25,48419.665,1629849600,1629935999 +2021-08-24,49684.076,1629763200,1629849599 +2021-08-23,49862.374,1629676800,1629763199 +2021-08-22,49148.507,1629590400,1629676799 +2021-08-21,49496.274,1629504000,1629590399 +2021-08-20,48021.919,1629417600,1629503999 +2021-08-19,45829.852,1629331200,1629417599 +2021-08-18,45287.096,1629244800,1629331199 +2021-08-17,46486.100,1629158400,1629244799 +2021-08-16,47512.239,1629072000,1629158399 +2021-08-15,47188.513,1628985600,1629071999 +2021-08-14,47939.138,1628899200,1628985599 +2021-08-13,46099.977,1628812800,1628899199 +2021-08-12,45879.530,1628726400,1628812799 +2021-08-11,46143.392,1628640000,1628726399 +2021-08-10,46408.392,1628553600,1628639999 +2021-08-09,45113.515,1628467200,1628553599 +2021-08-08,44930.180,1628380800,1628467199 +2021-08-07,43720.614,1628294400,1628380799 +2021-08-06,41930.393,1628208000,1628294399 +2021-08-05,40513.493,1628121600,1628207999 +2021-08-04,39070.468,1628035200,1628121599 +2021-08-03,39414.712,1627948800,1628035199 +2021-08-02,40143.583,1627862400,1627948799 +2021-08-01,42029.267,1627776000,1627862399 +2021-07-31,42278.660,1627689600,1627775999 +2021-07-30,41042.625,1627603200,1627689599 +2021-07-29,40279.205,1627516800,1627603199 +2021-07-28,40135.670,1627430400,1627516799 +2021-07-27,38248.530,1627344000,1627430399 +2021-07-26,37919.029,1627257600,1627343999 +2021-07-25,34745.118,1627171200,1627257599 +2021-07-24,34030.826,1627084800,1627171199 +2021-07-23,32900.017,1626998400,1627084799 +2021-07-22,32309.350,1626912000,1626998399 +2021-07-21,31283.773,1626825600,1626911999 +2021-07-20,30878.965,1626739200,1626825599 +2021-07-19,31827.211,1626652800,1626739199 +2021-07-18,31942.635,1626566400,1626652799 +2021-07-17,31634.730,1626480000,1626566399 +2021-07-16,31966.288,1626393600,1626479999 +2021-07-15,32982.993,1626307200,1626393599 +2021-07-14,32881.162,1626220800,1626307199 +2021-07-13,33217.884,1626134400,1626220799 +2021-07-12,34392.946,1626048000,1626134399 +2021-07-11,34022.923,1625961600,1626047999 +2021-07-10,34014.505,1625875200,1625961599 +2021-07-09,33467.119,1625788800,1625875199 +2021-07-08,33868.693,1625702400,1625788799 +2021-07-07,34588.166,1625616000,1625702399 +2021-07-06,34368.598,1625529600,1625615999 +2021-07-05,35308.198,1625443200,1625529599 +2021-07-04,35297.410,1625356800,1625443199 +2021-07-03,34344.352,1625270400,1625356799 +2021-07-02,33683.285,1625184000,1625270399 +2021-07-01,35019.705,1625097600,1625183999 +2021-06-30,35969.756,1625011200,1625097599 +2021-06-29,35471.054,1624924800,1625011199 +2021-06-28,34862.784,1624838400,1624924799 +2021-06-27,33427.000,1624752000,1624838399 +2021-06-26,32141.547,1624665600,1624751999 +2021-06-25,35052.241,1624579200,1624665599 +2021-06-24,34394.537,1624492800,1624579199 +2021-06-23,33595.805,1624406400,1624492799 +2021-06-22,32488.140,1624320000,1624406399 +2021-06-21,35677.329,1624233600,1624319999 +2021-06-20,35727.625,1624147200,1624233599 +2021-06-19,36010.035,1624060800,1624147199 +2021-06-18,38077.205,1623974400,1624060799 +2021-06-17,38931.506,1623888000,1623974399 +2021-06-16,40299.261,1623801600,1623887999 +2021-06-15,40897.500,1623715200,1623801599 +2021-06-14,40013.285,1623628800,1623715199 +2021-06-13,37431.786,1623542400,1623628799 +2021-06-12,37328.200,1623456000,1623542399 +2021-06-11,37106.425,1623369600,1623455999 +2021-06-10,37798.038,1623283200,1623369599 +2021-06-09,35454.806,1623196800,1623283199 +2021-06-08,33783.068,1623110400,1623196799 +2021-06-07,36305.205,1623024000,1623110399 +2021-06-06,35953.745,1622937600,1623023999 +2021-06-05,37365.677,1622851200,1622937599 +2021-06-04,39192.460,1622764800,1622851199 +2021-06-03,38501.425,1622678400,1622764799 +2021-06-02,37444.009,1622592000,1622678399 +2021-06-01,37530.862,1622505600,1622591999 +2021-05-31,36563.155,1622419200,1622505599 +2021-05-30,35443.015,1622332800,1622419199 +2021-05-29,36408.264,1622246400,1622332799 +2021-05-28,38606.744,1622160000,1622246399 +2021-05-27,39739.072,1622073600,1622159999 +2021-05-26,39514.268,1621987200,1622073599 +2021-05-25,39207.231,1621900800,1621987199 +2021-05-24,37232.154,1621814400,1621900799 +2021-05-23,37848.970,1621728000,1621814399 +2021-05-22,37964.528,1621641600,1621727999 +2021-05-21,41251.925,1621555200,1621641599 +2021-05-20,39593.601,1621468800,1621555199 +2021-05-19,43176.927,1621382400,1621468799 +2021-05-18,44615.032,1621296000,1621382399 +2021-05-17,46408.690,1621209600,1621295999 +2021-05-16,48233.331,1621123200,1621209599 +2021-05-15,50214.876,1621036800,1621123199 +2021-05-14,50543.334,1620950400,1621036799 +2021-05-13,50537.099,1620864000,1620950399 +2021-05-12,57281.825,1620777600,1620863999 +2021-05-11,56316.943,1620691200,1620777599 +2021-05-10,58831.657,1620604800,1620691199 +2021-05-09,58941.486,1620518400,1620604799 +2021-05-08,58383.858,1620432000,1620518399 +2021-05-07,57468.941,1620345600,1620431999 +2021-05-06,57865.295,1620259200,1620345599 +2021-05-05,55542.308,1620172800,1620259199 +2021-05-04,57160.541,1620086400,1620172799 +2021-05-03,57731.160,1620000000,1620086399 +2021-05-02,57823.921,1619913600,1619999999 +2021-05-01,58072.063,1619827200,1619913599 +2021-04-30,55681.883,1619740800,1619827199 +2021-04-29,54983.480,1619654400,1619740799 +2021-04-28,55583.214,1619568000,1619654399 +2021-04-27,54692.807,1619481600,1619567999 +2021-04-26,51637.437,1619395200,1619481599 +2021-04-25,50270.278,1619308800,1619395199 +2021-04-24,51084.099,1619222400,1619308799 +2021-04-23,51894.852,1619136000,1619222399 +2021-04-22,54600.009,1619049600,1619135999 +2021-04-21,56584.873,1618963200,1619049599 +2021-04-20,56318.806,1618876800,1618963199 +2021-04-19,56803.913,1618790400,1618876799 +2021-04-18,60151.515,1618704000,1618790399 +2021-04-17,61881.754,1618617600,1618703999 +2021-04-16,63350.325,1618531200,1618617599 +2021-04-15,63314.406,1618444800,1618531199 +2021-04-14,64180.611,1618358400,1618444799 +2021-04-13,61794.490,1618272000,1618358399 +2021-04-12,60551.401,1618185600,1618271999 +2021-04-11,60153.304,1618099200,1618185599 +2021-04-10,59673.020,1618012800,1618099199 +2021-04-09,58459.235,1617926400,1618012799 +2021-04-08,56980.422,1617840000,1617926399 +2021-04-07,58303.205,1617753600,1617839999 +2021-04-06,59247.372,1617667200,1617753599 +2021-04-05,58666.304,1617580800,1617667199 +2021-04-04,57752.490,1617494400,1617580799 +2021-04-03,59333.416,1617408000,1617494399 +2021-04-02,59395.712,1617321600,1617407999 +2021-04-01,59035.531,1617235200,1617321599 +2021-03-31,59270.769,1617148800,1617235199 +2021-03-30,58461.781,1617062400,1617148799 +2021-03-29,57044.303,1616976000,1617062399 +2021-03-28,56165.402,1616889600,1616975999 +2021-03-27,55732.430,1616803200,1616889599 +2021-03-26,53179.237,1616716800,1616803199 +2021-03-25,52760.964,1616630400,1616716799 +2021-03-24,55746.786,1616544000,1616630399 +2021-03-23,54992.157,1616457600,1616543999 +2021-03-22,57792.234,1616371200,1616457599 +2021-03-21,58303.830,1616284800,1616371199 +2021-03-20,58983.964,1616198400,1616284799 +2021-03-19,58557.552,1616112000,1616198399 +2021-03-18,59457.817,1616025600,1616111999 +2021-03-17,57860.492,1615939200,1616025599 +2021-03-16,56180.039,1615852800,1615939199 +2021-03-15,59850.639,1615766400,1615852799 +2021-03-14,61418.673,1615680000,1615766399 +2021-03-13,59456.172,1615593600,1615679999 +2021-03-12,57873.941,1615507200,1615593599 +2021-03-11,56998.318,1615420800,1615507199 +2021-03-10,56070.612,1615334400,1615420799 +2021-03-09,53552.498,1615248000,1615334399 +2021-03-08,51630.654,1615161600,1615247999 +2021-03-07,50140.960,1615075200,1615161599 +2021-03-06,48950.969,1614988800,1615075199 +2021-03-05,48919.999,1614902400,1614988799 +2021-03-04,51094.992,1614816000,1614902399 +2021-03-03,50489.786,1614729600,1614815999 +2021-03-02,49884.678,1614643200,1614729599 +2021-03-01,47430.860,1614556800,1614643199 +2021-02-28,46336.690,1614470400,1614556799 +2021-02-27,47306.290,1614384000,1614470399 +2021-02-26,47683.634,1614297600,1614383999 +2021-02-25,50730.027,1614211200,1614297599 +2021-02-24,50056.735,1614124800,1614211199 +2021-02-23,54099.981,1614038400,1614124799 +2021-02-22,57411.012,1613952000,1614038399 +2021-02-21,57135.681,1613865600,1613951999 +2021-02-20,56685.566,1613779200,1613865599 +2021-02-19,53896.919,1613692800,1613779199 +2021-02-18,52292.826,1613606400,1613692799 +2021-02-17,50821.782,1613520000,1613606399 +2021-02-16,49136.002,1613433600,1613519999 +2021-02-15,48764.220,1613347200,1613433599 +2021-02-14,48344.941,1613260800,1613347199 +2021-02-13,47694.612,1613174400,1613260799 +2021-02-12,48323.161,1613088000,1613174399 +2021-02-11,46666.321,1613001600,1613087999 +2021-02-10,46893.163,1612915200,1613001599 +2021-02-09,47213.444,1612828800,1612915199 +2021-02-08,42541.307,1612742400,1612828799 +2021-02-07,39457.706,1612656000,1612742399 +2021-02-06,39579.298,1612569600,1612655999 +2021-02-05,37628.923,1612483200,1612569599 +2021-02-04,38196.808,1612396800,1612483199 +2021-02-03,36520.750,1612310400,1612396799 +2021-02-02,34739.910,1612224000,1612310399 +2021-02-01,33841.421,1612137600,1612223999 +2021-01-31,34275.232,1612051200,1612137599 +2021-01-30,34566.617,1611964800,1612051199 +2021-01-29,35826.659,1611878400,1611964799 +2021-01-28,32078.240,1611792000,1611878399 +2021-01-27,32503.856,1611705600,1611791999 +2021-01-26,32539.682,1611619200,1611705599 +2021-01-25,33521.364,1611532800,1611619199 +2021-01-24,32511.300,1611446400,1611532799 +2021-01-23,33134.953,1611360000,1611446399 +2021-01-22,32319.580,1611273600,1611359999 +2021-01-21,35477.524,1611187200,1611273599 +2021-01-20,36186.844,1611100800,1611187199 +2021-01-19,37166.948,1611014400,1611100799 +2021-01-18,36594.257,1610928000,1611014399 +2021-01-17,36372.142,1610841600,1610927999 +2021-01-16,37372.189,1610755200,1610841599 +2021-01-15,39462.899,1610668800,1610755199 +2021-01-14,38697.068,1610582400,1610668799 +2021-01-13,35843.128,1610496000,1610582399 +2021-01-12,36037.432,1610409600,1610495999 +2021-01-11,38223.374,1610323200,1610409599 +2021-01-10,40669.898,1610236800,1610323199 +2021-01-09,40934.638,1610150400,1610236799 +2021-01-08,40643.673,1610064000,1610150399 +2021-01-07,38489.420,1609977600,1610063999 +2021-01-06,35399.960,1609891200,1609977599 +2021-01-05,33191.642,1609804800,1609891199 +2021-01-04,33251.425,1609718400,1609804799 +2021-01-03,33432.856,1609632000,1609718399 +2021-01-02,31244.154,1609545600,1609631999 +2021-01-01,29249.462,1609459200,1609545599 +2020-12-31,29067.885,1609372800,1609459199 +2020-12-30,28156.682,1609286400,1609372799 +2020-12-29,27231.280,1609200000,1609286399 +2020-12-28,26850.457,1609113600,1609199999 +2020-12-27,27397.260,1609027200,1609113599 +2020-12-26,25699.679,1608940800,1609027199 +2020-12-25,24217.158,1608854400,1608940799 +2020-12-24,23498.609,1608768000,1608854399 +2020-12-23,23913.553,1608681600,1608767999 +2020-12-22,23272.776,1608595200,1608681599 +2020-12-21,23776.967,1608508800,1608595199 +2020-12-20,24054.815,1608422400,1608508799 +2020-12-19,23604.269,1608336000,1608422399 +2020-12-18,23017.974,1608249600,1608335999 +2020-12-17,22503.155,1608163200,1608249599 +2020-12-16,20409.783,1608076800,1608163199 +2020-12-15,19407.349,1607990400,1608076799 +2020-12-14,19264.128,1607904000,1607990399 +2020-12-13,19094.277,1607817600,1607903999 +2020-12-12,18461.304,1607731200,1607817599 +2020-12-11,18236.776,1607644800,1607731199 +2020-12-10,18541.855,1607558400,1607644799 +2020-12-09,18476.762,1607472000,1607558399 +2020-12-08,19219.097,1607385600,1607471999 +2020-12-07,19383.667,1607299200,1607385599 +2020-12-06,19264.136,1607212800,1607299199 +2020-12-05,18913.960,1607126400,1607212799 +2020-12-04,19470.744,1607040000,1607126399 +2020-12-03,19402.534,1606953600,1607039999 +2020-12-02,19043.509,1606867200,1606953599 +2020-12-01,19784.801,1606780800,1606867199 +2020-11-30,18992.147,1606694400,1606780799 +2020-11-29,18017.769,1606608000,1606694399 +2020-11-28,17490.192,1606521600,1606607999 +2020-11-27,17288.671,1606435200,1606521599 +2020-11-26,18823.599,1606348800,1606435199 +2020-11-25,19306.511,1606262400,1606348799 +2020-11-24,18897.877,1606176000,1606262399 +2020-11-23,18575.587,1606089600,1606175999 +2020-11-22,18707.445,1606003200,1606089599 +2020-11-21,18810.909,1605916800,1606003199 +2020-11-20,18299.298,1605830400,1605916799 +2020-11-19,17954.059,1605744000,1605830399 +2020-11-18,18069.993,1605657600,1605743999 +2020-11-17,17266.873,1605571200,1605657599 +2020-11-16,16395.738,1605484800,1605571199 +2020-11-15,16099.948,1605398400,1605484799 +2020-11-14,16320.047,1605312000,1605398399 +2020-11-13,16380.241,1605225600,1605311999 +2020-11-12,15995.776,1605139200,1605225599 +2020-11-11,15623.732,1605052800,1605139199 +2020-11-10,15371.350,1604966400,1605052799 +2020-11-09,15638.257,1604880000,1604966399 +2020-11-08,15214.242,1604793600,1604879999 +2020-11-07,15655.186,1604707200,1604793599 +2020-11-06,15755.855,1604620800,1604707199 +2020-11-05,14925.555,1604534400,1604620799 +2020-11-04,14114.782,1604448000,1604534399 +2020-11-03,13795.384,1604361600,1604447999 +2020-11-02,13793.925,1604275200,1604361599 +2020-11-01,13838.209,1604188800,1604275199 +2020-10-31,13769.855,1604102400,1604188799 +2020-10-30,13559.285,1604016000,1604102399 +2020-10-29,13453.171,1603929600,1604015999 +2020-10-28,13738.526,1603843200,1603929599 +2020-10-27,13416.585,1603756800,1603843199 +2020-10-26,13118.631,1603670400,1603756799 +2020-10-25,13221.635,1603584000,1603670399 +2020-10-24,13034.600,1603497600,1603583999 +2020-10-23,12989.410,1603411200,1603497599 +2020-10-22,12981.301,1603324800,1603411199 +2020-10-21,12549.418,1603238400,1603324799 +2020-10-20,11877.791,1603152000,1603238399 +2020-10-19,11650.012,1603065600,1603151999 +2020-10-18,11424.072,1602979200,1603065599 +2020-10-17,11351.447,1602892800,1602979199 +2020-10-16,11519.085,1602806400,1602892799 +2020-10-15,11495.330,1602720000,1602806399 +2020-10-14,11483.301,1602633600,1602719999 +2020-10-13,11536.827,1602547200,1602633599 +2020-10-12,11532.746,1602460800,1602547199 +2020-10-11,11362.082,1602374400,1602460799 +2020-10-10,11257.210,1602288000,1602374399 +2020-10-09,11011.007,1602201600,1602287999 +2020-10-08,10800.619,1602115200,1602201599 +2020-10-07,10640.713,1602028800,1602115199 +2020-10-06,10790.146,1601942400,1602028799 +2020-10-05,10725.864,1601856000,1601942399 +2020-10-04,10613.165,1601769600,1601855999 +2020-10-03,10582.035,1601683200,1601769599 +2020-10-02,10641.861,1601596800,1601683199 +2020-10-01,10840.215,1601510400,1601596799 +2020-09-30,10842.145,1601424000,1601510399 +2020-09-29,10774.034,1601337600,1601423999 +2020-09-28,10855.631,1601251200,1601337599 +2020-09-27,10762.266,1601164800,1601251199 +2020-09-26,10727.926,1601078400,1601164799 +2020-09-25,10741.122,1600992000,1601078399 +2020-09-24,10498.554,1600905600,1600991999 +2020-09-23,10529.806,1600819200,1600905599 +2020-09-22,10486.272,1600732800,1600819199 +2020-09-21,10951.624,1600646400,1600732799 +2020-09-20,11083.429,1600560000,1600646399 +2020-09-19,11036.959,1600473600,1600559999 +2020-09-18,10979.264,1600387200,1600473599 +2020-09-17,10990.098,1600300800,1600387199 +2020-09-16,10930.666,1600214400,1600300799 +2020-09-15,10798.960,1600128000,1600214399 +2020-09-14,10532.291,1600041600,1600127999 +2020-09-13,10499.904,1599955200,1600041599 +2020-09-12,10431.100,1599868800,1599955199 +2020-09-11,10361.896,1599782400,1599868799 +2020-09-10,10343.374,1599696000,1599782399 +2020-09-09,10225.995,1599609600,1599695999 +2020-09-08,10385.831,1599523200,1599609599 +2020-09-07,10320.234,1599436800,1599523199 +2020-09-06,10254.587,1599350400,1599436799 +2020-09-05,10498.304,1599264000,1599350399 +2020-09-04,10380.603,1599177600,1599263999 +2020-09-03,11411.944,1599091200,1599177599 +2020-09-02,11935.038,1599004800,1599091199 +2020-09-01,11847.091,1598918400,1599004799 +2020-08-31,11739.921,1598832000,1598918399 +2020-08-30,11588.148,1598745600,1598831999 +2020-08-29,11526.833,1598659200,1598745599 +2020-08-28,11412.141,1598572800,1598659199 +2020-08-27,11506.010,1598486400,1598572799 +2020-08-26,11429.278,1598400000,1598486399 +2020-08-25,11759.029,1598313600,1598399999 +2020-08-24,11735.086,1598227200,1598313599 +2020-08-23,11693.890,1598140800,1598227199 +2020-08-22,11611.206,1598054400,1598140799 +2020-08-21,11864.883,1597968000,1598054399 +2020-08-20,11810.632,1597881600,1597967999 +2020-08-19,11988.324,1597795200,1597881599 +2020-08-18,12318.547,1597708800,1597795199 +2020-08-17,12143.669,1597622400,1597708799 +2020-08-16,11885.011,1597536000,1597622399 +2020-08-15,11861.098,1597449600,1597535999 +2020-08-14,11798.248,1597363200,1597449599 +2020-08-13,11670.078,1597276800,1597363199 +2020-08-12,11502.390,1597190400,1597276799 +2020-08-11,11906.472,1597104000,1597190399 +2020-08-10,11849.272,1597017600,1597103999 +2020-08-09,11771.614,1596931200,1597017599 +2020-08-08,11697.076,1596844800,1596931199 +2020-08-07,11831.701,1596758400,1596844799 +2020-08-06,11816.907,1596672000,1596758399 +2020-08-05,11482.724,1596585600,1596671999 +2020-08-04,11309.969,1596499200,1596585599 +2020-08-03,11267.700,1596412800,1596499199 +2020-08-02,11938.237,1596326400,1596412799 +2020-08-01,11592.213,1596240000,1596326399 +2020-07-31,11263.052,1596153600,1596239999 +2020-07-30,11120.944,1596067200,1596153599 +2020-07-29,11093.790,1595980800,1596067199 +2020-07-28,11110.567,1595894400,1595980799 +2020-07-27,10630.863,1595808000,1595894399 +2020-07-26,9885.370,1595721600,1595807999 +2020-07-25,9632.050,1595635200,1595721599 +2020-07-24,9614.841,1595548800,1595635199 +2020-07-23,9575.414,1595462400,1595548799 +2020-07-22,9454.479,1595376000,1595462399 +2020-07-21,9290.790,1595289600,1595375999 +2020-07-20,9209.837,1595203200,1595289599 +2020-07-19,9191.619,1595116800,1595203199 +2020-07-18,9176.329,1595030400,1595116799 +2020-07-17,9155.954,1594944000,1595030399 +2020-07-16,9210.739,1594857600,1594943999 +2020-07-15,9261.713,1594771200,1594857599 +2020-07-14,9257.875,1594684800,1594771199 +2020-07-13,9308.797,1594598400,1594684799 +2020-07-12,9272.118,1594512000,1594598399 +2020-07-11,9280.100,1594425600,1594511999 +2020-07-10,9264.229,1594339200,1594425599 +2020-07-09,9428.998,1594252800,1594339199 +2020-07-08,9355.374,1594166400,1594252799 +2020-07-07,9351.537,1594080000,1594166399 +2020-07-06,9210.241,1593993600,1594079999 +2020-07-05,9134.471,1593907200,1593993599 +2020-07-04,9123.977,1593820800,1593907199 +2020-07-03,9099.555,1593734400,1593820799 +2020-07-02,9240.670,1593648000,1593734399 +2020-07-01,9209.576,1593561600,1593647999 +2020-06-30,9185.066,1593475200,1593561599 +2020-06-29,9172.756,1593388800,1593475199 +2020-06-28,9096.681,1593302400,1593388799 +2020-06-27,9177.014,1593216000,1593302399 +2020-06-26,9272.063,1593129600,1593215999 +2020-06-25,9313.729,1593043200,1593129599 +2020-06-24,9641.667,1592956800,1593043199 +2020-06-23,9698.118,1592870400,1592956799 +2020-06-22,9496.345,1592784000,1592870399 +2020-06-21,9400.570,1592697600,1592783999 +2020-06-20,9344.640,1592611200,1592697599 +2020-06-19,9403.111,1592524800,1592611199 +2020-06-18,9461.714,1592438400,1592524799 +2020-06-17,9531.487,1592352000,1592438399 +2020-06-16,9494.259,1592265600,1592351999 +2020-06-15,9418.979,1592179200,1592265599 +2020-06-14,9470.195,1592092800,1592179199 +2020-06-13,9468.785,1592006400,1592092799 +2020-06-12,9421.544,1591920000,1592006399 +2020-06-11,9894.426,1591833600,1591919999 +2020-06-10,9869.392,1591747200,1591833599 +2020-06-09,9807.647,1591660800,1591747199 +2020-06-08,9763.130,1591574400,1591660799 +2020-06-07,9715.428,1591488000,1591574399 +2020-06-06,9679.787,1591401600,1591487999 +2020-06-05,9814.719,1591315200,1591401599 +2020-06-04,9754.872,1591228800,1591315199 +2020-06-03,9597.669,1591142400,1591228799 +2020-06-02,10170.702,1591056000,1591142399 +2020-06-01,9843.362,1590969600,1591055999 +2020-05-31,9694.273,1590883200,1590969599 +2020-05-30,9562.067,1590796800,1590883199 +2020-05-29,9549.747,1590710400,1590796799 +2020-05-28,9372.007,1590624000,1590710399 +2020-05-27,9022.929,1590537600,1590623999 +2020-05-26,8939.767,1590451200,1590537599 +2020-05-25,8855.292,1590364800,1590451199 +2020-05-24,9228.860,1590278400,1590364799 +2020-05-23,9230.797,1590192000,1590278399 +2020-05-22,9152.166,1590105600,1590191999 +2020-05-21,9538.725,1590019200,1590105599 +2020-05-20,9787.598,1589932800,1590019199 +2020-05-19,9788.597,1589846400,1589932799 +2020-05-18,9787.036,1589760000,1589846399 +2020-05-17,9609.548,1589673600,1589759999 +2020-05-16,9431.973,1589587200,1589673599 +2020-05-15,9787.784,1589500800,1589587199 +2020-05-14,9567.235,1589414400,1589500799 +2020-05-13,9084.316,1589328000,1589414399 +2020-05-12,8762.280,1589241600,1589327999 +2020-05-11,8927.688,1589155200,1589241599 +2020-05-10,9554.216,1589068800,1589155199 +2020-05-09,9857.416,1588982400,1589068799 +2020-05-08,9969.406,1588896000,1588982399 +2020-05-07,9578.018,1588809600,1588895999 +2020-05-06,9183.128,1588723200,1588809599 +2020-05-05,8968.208,1588636800,1588723199 +2020-05-04,8914.653,1588550400,1588636799 +2020-05-03,9065.772,1588464000,1588550399 +2020-05-02,8907.545,1588377600,1588463999 +2020-05-01,8827.303,1588291200,1588377599 +2020-04-30,9091.113,1588204800,1588291199 +2020-04-29,8313.196,1588118400,1588204799 +2020-04-28,7772.740,1588032000,1588118399 +2020-04-27,7721.401,1587945600,1588031999 +2020-04-26,7601.564,1587859200,1587945599 +2020-04-25,7550.127,1587772800,1587859199 +2020-04-24,7527.547,1587686400,1587772799 +2020-04-23,7363.374,1587600000,1587686399 +2020-04-22,6988.284,1587513600,1587599999 +2020-04-21,6879.705,1587427200,1587513599 +2020-04-20,7162.137,1587340800,1587427199 +2020-04-19,7238.814,1587254400,1587340799 +2020-04-18,7148.468,1587168000,1587254399 +2020-04-17,7111.623,1587081600,1587167999 +2020-04-16,6884.328,1586995200,1587081599 +2020-04-15,6887.926,1586908800,1586995199 +2020-04-14,6899.010,1586822400,1586908799 +2020-04-13,6925.828,1586736000,1586822399 +2020-04-12,7012.769,1586649600,1586735999 +2020-04-11,6900.375,1586563200,1586649599 +2020-04-10,7289.543,1586476800,1586563199 +2020-04-09,7353.264,1586390400,1586476799 +2020-04-08,7286.910,1586304000,1586390399 +2020-04-07,7372.667,1586217600,1586303999 +2020-04-06,7040.368,1586131200,1586217599 +2020-04-05,6860.987,1586044800,1586131199 +2020-04-04,6800.805,1585958400,1586044799 +2020-04-03,6903.632,1585872000,1585958399 +2020-04-02,6851.742,1585785600,1585871999 +2020-04-01,6510.506,1585699200,1585785599 +2020-03-31,6447.275,1585612800,1585699199 +2020-03-30,6223.468,1585526400,1585612799 +2020-03-29,6241.957,1585440000,1585526399 +2020-03-28,6378.656,1585353600,1585439999 +2020-03-27,6778.945,1585267200,1585353599 +2020-03-26,6715.100,1585180800,1585267199 +2020-03-25,6825.158,1585094400,1585180799 +2020-03-24,6620.554,1585008000,1585094399 +2020-03-23,6168.629,1584921600,1585007999 +2020-03-22,6274.138,1584835200,1584921599 +2020-03-21,6319.858,1584748800,1584835199 +2020-03-20,6504.488,1584662400,1584748799 +2020-03-19,5868.585,1584576000,1584662399 +2020-03-18,5359.918,1584489600,1584575999 +2020-03-17,5227.625,1584403200,1584489599 +2020-03-16,5374.039,1584316800,1584403199 +2020-03-15,5516.941,1584230400,1584316799 +2020-03-14,5598.515,1584144000,1584230399 +2020-03-13,5345.793,1584057600,1584143999 +2020-03-12,7942.774,1583971200,1584057599 +2020-03-11,7930.406,1583884800,1583971199 +2020-03-10,8036.488,1583798400,1583884799 +2020-03-09,8088.865,1583712000,1583798399 +2020-03-08,8898.958,1583625600,1583711999 +2020-03-07,9150.702,1583539200,1583625599 +2020-03-06,9106.577,1583452800,1583539199 +2020-03-05,8946.484,1583366400,1583452799 +2020-03-04,8800.921,1583280000,1583366399 +2020-03-03,8907.408,1583193600,1583279999 +2020-03-02,8752.733,1583107200,1583193599 +2020-03-01,8630.408,1583020800,1583107199 +2020-02-29,8766.636,1582934400,1583020799 +2020-02-28,8852.649,1582848000,1582934399 +2020-02-27,8835.407,1582761600,1582847999 +2020-02-26,9347.812,1582675200,1582761599 +2020-02-25,9784.106,1582588800,1582675199 +2020-02-24,9962.827,1582502400,1582588799 +2020-02-23,9807.189,1582416000,1582502399 +2020-02-22,9692.172,1582329600,1582415999 +2020-02-21,9673.712,1582243200,1582329599 +2020-02-20,9634.487,1582156800,1582243199 +2020-02-19,10183.796,1582070400,1582156799 +2020-02-18,9955.214,1581984000,1582070399 +2020-02-17,9940.076,1581897600,1581983999 +2020-02-16,9970.214,1581811200,1581897599 +2020-02-15,10347.276,1581724800,1581811199 +2020-02-14,10294.841,1581638400,1581724799 +2020-02-13,10386.231,1581552000,1581638399 +2020-02-12,10308.557,1581465600,1581551999 +2020-02-11,10071.658,1581379200,1581465599 +2020-02-10,10141.562,1581292800,1581379199 +2020-02-09,10013.401,1581206400,1581292799 +2020-02-08,9894.719,1581120000,1581206399 +2020-02-07,9815.778,1581033600,1581119999 +2020-02-06,9720.676,1580947200,1581033599 +2020-02-05,9429.853,1580860800,1580947199 +2020-02-04,9318.223,1580774400,1580860799 +2020-02-03,9438.867,1580688000,1580774399 +2020-02-02,9416.981,1580601600,1580687999 +2020-02-01,9397.382,1580515200,1580601599 +2020-01-31,9505.557,1580428800,1580515199 +2020-01-30,9424.932,1580342400,1580428799 +2020-01-29,9380.656,1580256000,1580342399 +2020-01-28,9115.502,1580169600,1580255999 +2020-01-27,8776.664,1580083200,1580169599 +2020-01-26,8476.566,1579996800,1580083199 +2020-01-25,8436.017,1579910400,1579996799 +2020-01-24,8461.025,1579824000,1579910399 +2020-01-23,8678.652,1579737600,1579823999 +2020-01-22,8759.671,1579651200,1579737599 +2020-01-21,8699.518,1579564800,1579651199 +2020-01-20,8722.859,1579478400,1579564799 +2020-01-19,9048.164,1579392000,1579478399 +2020-01-18,8942.130,1579305600,1579391999 +2020-01-17,8855.188,1579219200,1579305599 +2020-01-16,8827.327,1579132800,1579219199 +2020-01-15,8847.195,1579046400,1579132799 +2020-01-14,8475.401,1578960000,1579046399 +2020-01-13,8175.873,1578873600,1578959999 +2020-01-12,8100.403,1578787200,1578873599 +2020-01-11,8211.072,1578700800,1578787199 +2020-01-10,7991.024,1578614400,1578700799 +2020-01-09,8047.811,1578528000,1578614399 +2020-01-08,8292.279,1578441600,1578527999 +2020-01-07,7962.329,1578355200,1578441599 +2020-01-06,7562.965,1578268800,1578355199 +2020-01-05,7415.957,1578182400,1578268799 +2020-01-04,7348.946,1578096000,1578182399 +2020-01-03,7176.199,1578009600,1578095999 +2020-01-02,7218.781,1577923200,1578009599 +2020-01-01,7224.324,1577836800,1577923199 +2019-12-31,7272.797,1577750400,1577836799 +2019-12-30,7393.013,1577664000,1577750399 +2019-12-29,7399.953,1577577600,1577663999 +2019-12-28,7298.016,1577491200,1577577599 +2019-12-27,7234.821,1577404800,1577491199 +2019-12-26,7307.252,1577318400,1577404799 +2019-12-25,7261.176,1577232000,1577318399 +2019-12-24,7367.954,1577145600,1577231999 +2019-12-23,7578.280,1577059200,1577145599 +2019-12-22,7311.641,1576972800,1577059199 +2019-12-21,7189.186,1576886400,1576972799 +2019-12-20,7180.013,1576800000,1576886399 +2019-12-19,7303.335,1576713600,1576799999 +2019-12-18,6966.133,1576627200,1576713599 +2019-12-17,6911.795,1576540800,1576627199 +2019-12-16,7128.542,1576454400,1576540799 +2019-12-15,7113.861,1576368000,1576454399 +2019-12-14,7263.174,1576281600,1576367999 +2019-12-13,7243.484,1576195200,1576281599 +2019-12-12,7227.915,1576108800,1576195199 +2019-12-11,7246.800,1576022400,1576108799 +2019-12-10,7368.380,1575936000,1576022399 +2019-12-09,7545.675,1575849600,1575935999 +2019-12-08,7519.788,1575763200,1575849599 +2019-12-07,7550.818,1575676800,1575763199 +2019-12-06,7460.514,1575590400,1575676799 +2019-12-05,7328.143,1575504000,1575590399 +2019-12-04,7424.284,1575417600,1575503999 +2019-12-03,7346.058,1575331200,1575417599 +2019-12-02,7412.381,1575244800,1575331199 +2019-12-01,7551.710,1575158400,1575244799 +2019-11-30,7760.321,1575072000,1575158399 +2019-11-29,7615.591,1574985600,1575071999 +2019-11-28,7565.099,1574899200,1574985599 +2019-11-27,7394.714,1574812800,1574899199 +2019-11-26,7219.731,1574726400,1574812799 +2019-11-25,7138.706,1574640000,1574726399 +2019-11-24,7318.073,1574553600,1574639999 +2019-11-23,7305.548,1574467200,1574553599 +2019-11-22,7660.781,1574380800,1574467199 +2019-11-21,8113.980,1574294400,1574380799 +2019-11-20,8159.024,1574208000,1574294399 +2019-11-19,8210.414,1574121600,1574207999 +2019-11-18,8504.159,1574035200,1574121599 +2019-11-17,8545.214,1573948800,1574035199 +2019-11-16,8500.924,1573862400,1573948799 +2019-11-15,8693.051,1573776000,1573862399 +2019-11-14,8789.107,1573689600,1573775999 +2019-11-13,8807.509,1573603200,1573689599 +2019-11-12,8780.726,1573516800,1573603199 +2019-11-11,9051.165,1573430400,1573516799 +2019-11-10,8949.528,1573344000,1573430399 +2019-11-09,8834.520,1573257600,1573343999 +2019-11-08,9234.925,1573171200,1573257599 +2019-11-07,9336.183,1573084800,1573171199 +2019-11-06,9356.760,1572998400,1573084799 +2019-11-05,9405.768,1572912000,1572998399 +2019-11-04,9333.360,1572825600,1572911999 +2019-11-03,9321.804,1572739200,1572825599 +2019-11-02,9283.720,1572652800,1572739199 +2019-11-01,9203.340,1572566400,1572652799 +2019-10-31,9240.740,1572480000,1572566399 +2019-10-30,9408.955,1572393600,1572479999 +2019-10-29,9367.962,1572307200,1572393599 +2019-10-28,9678.312,1572220800,1572307199 +2019-10-27,9478.833,1572134400,1572220799 +2019-10-26,9382.530,1572048000,1572134399 +2019-10-25,8055.788,1571961600,1572047999 +2019-10-24,7490.539,1571875200,1571961599 +2019-10-23,8044.376,1571788800,1571875199 +2019-10-22,8246.816,1571702400,1571788799 +2019-10-21,8240.389,1571616000,1571702399 +2019-10-20,8104.446,1571529600,1571615999 +2019-10-19,7989.369,1571443200,1571529599 +2019-10-18,8090.965,1571356800,1571443199 +2019-10-17,8058.070,1571270400,1571356799 +2019-10-16,8178.534,1571184000,1571270399 +2019-10-15,8367.586,1571097600,1571183999 +2019-10-14,8326.352,1571011200,1571097599 +2019-10-13,8372.797,1570924800,1571011199 +2019-10-12,8330.818,1570838400,1570924799 +2019-10-11,8636.122,1570752000,1570838399 +2019-10-10,8596.546,1570665600,1570751999 +2019-10-09,8405.278,1570579200,1570665599 +2019-10-08,8252.889,1570492800,1570579199 +2019-10-07,8080.398,1570406400,1570492799 +2019-10-06,8139.095,1570320000,1570406399 +2019-10-05,8157.660,1570233600,1570319999 +2019-10-04,8229.144,1570147200,1570233599 +2019-10-03,8367.613,1570060800,1570147199 +2019-10-02,8330.783,1569974400,1570060799 +2019-10-01,8382.146,1569888000,1569974399 +2019-09-30,8172.650,1569801600,1569887999 +2019-09-29,8215.584,1569715200,1569801599 +2019-09-28,8206.104,1569628800,1569715199 +2019-09-27,8157.593,1569542400,1569628799 +2019-09-26,8448.330,1569456000,1569542399 +2019-09-25,8648.823,1569369600,1569455999 +2019-09-24,9757.080,1569283200,1569369599 +2019-09-23,10043.222,1569196800,1569283199 +2019-09-22,10036.335,1569110400,1569196799 +2019-09-21,10178.746,1569024000,1569110399 +2019-09-20,10246.857,1568937600,1569023999 +2019-09-19,10211.370,1568851200,1568937599 +2019-09-18,10231.111,1568764800,1568851199 +2019-09-17,10273.278,1568678400,1568764799 +2019-09-16,10338.526,1568592000,1568678399 +2019-09-15,10358.722,1568505600,1568591999 +2019-09-14,10382.559,1568419200,1568505599 +2019-09-13,10415.387,1568332800,1568419199 +2019-09-12,10296.684,1568246400,1568332799 +2019-09-11,10164.314,1568160000,1568246399 +2019-09-10,10349.208,1568073600,1568159999 +2019-09-09,10425.826,1567987200,1568073599 +2019-09-08,10521.431,1567900800,1567987199 +2019-09-07,10424.390,1567814400,1567900799 +2019-09-06,10729.933,1567728000,1567814399 +2019-09-05,10597.501,1567641600,1567727999 +2019-09-04,10676.451,1567555200,1567641599 +2019-09-03,10528.100,1567468800,1567555199 +2019-09-02,10059.721,1567382400,1567468799 +2019-09-01,9683.308,1567296000,1567382399 +2019-08-31,9622.974,1567209600,1567295999 +2019-08-30,9570.413,1567123200,1567209599 +2019-08-29,9755.839,1567036800,1567123199 +2019-08-28,10238.471,1566950400,1567036799 +2019-08-27,10380.720,1566864000,1566950399 +2019-08-26,10353.345,1566777600,1566863999 +2019-08-25,10218.855,1566691200,1566777599 +2019-08-24,10396.981,1566604800,1566691199 +2019-08-23,10269.603,1566518400,1566604799 +2019-08-22,10184.094,1566432000,1566518399 +2019-08-21,10764.528,1566345600,1566431999 +2019-08-20,10905.301,1566259200,1566345599 +2019-08-19,10610.379,1566172800,1566259199 +2019-08-18,10350.882,1566086400,1566172799 +2019-08-17,10396.086,1566000000,1566086399 +2019-08-16,10401.031,1565913600,1565999999 +2019-08-15,10242.094,1565827200,1565913599 +2019-08-14,10901.106,1565740800,1565827199 +2019-08-13,11422.033,1565654400,1565740799 +2019-08-12,11570.902,1565568000,1565654399 +2019-08-11,11442.189,1565481600,1565567999 +2019-08-10,11891.861,1565395200,1565481599 +2019-08-09,12002.669,1565308800,1565395199 +2019-08-08,11987.834,1565222400,1565308799 +2019-08-07,11774.932,1565136000,1565222399 +2019-08-06,11977.572,1565049600,1565135999 +2019-08-05,11394.916,1564963200,1565049599 +2019-08-04,10899.916,1564876800,1564963199 +2019-08-03,10701.167,1564790400,1564876799 +2019-08-02,10504.738,1564704000,1564790399 +2019-08-01,10248.758,1564617600,1564703999 +2019-07-31,9833.979,1564531200,1564617599 +2019-07-30,9611.057,1564444800,1564531199 +2019-07-29,9615.896,1564358400,1564444799 +2019-07-28,9541.144,1564272000,1564358399 +2019-07-27,9992.190,1564185600,1564271999 +2019-07-26,9902.673,1564099200,1564185599 +2019-07-25,9965.879,1564012800,1564099199 +2019-07-24,9898.815,1563926400,1564012799 +2019-07-23,10346.190,1563840000,1563926399 +2019-07-22,10623.384,1563753600,1563839999 +2019-07-21,10777.596,1563667200,1563753599 +2019-07-20,10771.219,1563580800,1563667199 +2019-07-19,10664.064,1563494400,1563580799 +2019-07-18,10189.473,1563408000,1563494399 +2019-07-17,9686.396,1563321600,1563407999 +2019-07-16,10926.858,1563235200,1563321599 +2019-07-15,10628.486,1563148800,1563235199 +2019-07-14,11426.555,1563062400,1563148799 +2019-07-13,11791.036,1562976000,1563062399 +2019-07-12,11618.447,1562889600,1562975999 +2019-07-11,12124.390,1562803200,1562889599 +2019-07-10,12829.653,1562716800,1562803199 +2019-07-09,12503.824,1562630400,1562716799 +2019-07-08,11873.710,1562544000,1562630399 +2019-07-07,11415.179,1562457600,1562543999 +2019-07-06,11313.733,1562371200,1562457599 +2019-07-05,11302.057,1562284800,1562371199 +2019-07-04,11973.072,1562198400,1562284799 +2019-07-03,11391.677,1562112000,1562198399 +2019-07-02,10773.204,1562025600,1562111999 +2019-07-01,11101.426,1561939200,1562025599 +2019-06-30,12207.860,1561852800,1561939199 +2019-06-29,12492.976,1561766400,1561852799 +2019-06-28,11913.251,1561680000,1561766399 +2019-06-27,13293.354,1561593600,1561679999 +2019-06-26,12881.166,1561507200,1561593599 +2019-06-25,11412.002,1561420800,1561507199 +2019-06-24,10985.934,1561334400,1561420799 +2019-06-23,10960.617,1561248000,1561334399 +2019-06-22,10691.120,1561161600,1561247999 +2019-06-21,9876.206,1561075200,1561161599 +2019-06-20,9472.310,1560988800,1561075199 +2019-06-19,9228.944,1560902400,1560988799 +2019-06-18,9347.260,1560816000,1560902399 +2019-06-17,9215.109,1560729600,1560815999 +2019-06-16,9126.829,1560643200,1560729599 +2019-06-15,8794.233,1560556800,1560643199 +2019-06-14,8512.912,1560470400,1560556799 +2019-06-13,8271.572,1560384000,1560470399 +2019-06-12,8080.940,1560297600,1560383999 +2019-06-11,8020.109,1560211200,1560297599 +2019-06-10,7901.183,1560124800,1560211199 +2019-06-09,7990.452,1560038400,1560124799 +2019-06-08,8078.737,1559952000,1560038399 +2019-06-07,7978.734,1559865600,1559951999 +2019-06-06,7888.585,1559779200,1559865599 +2019-06-05,7844.046,1559692800,1559779199 +2019-06-04,8341.435,1559606400,1559692799 +2019-06-03,8771.296,1559520000,1559606399 +2019-06-02,8702.483,1559433600,1559519999 +2019-06-01,8616.719,1559347200,1559433599 +2019-05-31,8473.462,1559260800,1559347199 +2019-05-30,8830.362,1559174400,1559260799 +2019-05-29,8743.011,1559088000,1559174399 +2019-05-28,8843.155,1559001600,1559087999 +2019-05-27,8860.362,1558915200,1559001599 +2019-05-26,8431.565,1558828800,1558915199 +2019-05-25,8080.412,1558742400,1558828799 +2019-05-24,8028.486,1558656000,1558742399 +2019-05-23,7859.049,1558569600,1558655999 +2019-05-22,7988.358,1558483200,1558569599 +2019-05-21,8047.550,1558396800,1558483199 +2019-05-20,8172.975,1558310400,1558396799 +2019-05-19,7783.071,1558224000,1558310399 +2019-05-18,7452.615,1558137600,1558223999 +2019-05-17,7942.067,1558051200,1558137599 +2019-05-16,8232.179,1557964800,1558051199 +2019-05-15,8091.954,1557878400,1557964799 +2019-05-14,8029.218,1557792000,1557878399 +2019-05-13,7532.545,1557705600,1557791999 +2019-05-12,7356.245,1557619200,1557705599 +2019-05-11,6867.801,1557532800,1557619199 +2019-05-10,6307.319,1557446400,1557532799 +2019-05-09,6084.886,1557360000,1557446399 +2019-05-08,5904.947,1557273600,1557359999 +2019-05-07,5866.759,1557187200,1557273599 +2019-05-06,5777.516,1557100800,1557187199 +2019-05-05,5820.793,1557014400,1557100799 +2019-05-04,5793.246,1556928000,1557014399 +2019-05-03,5657.717,1556841600,1556927999 +2019-05-02,5453.703,1556755200,1556841599 +2019-05-01,5353.354,1556668800,1556755199 +2019-04-30,5312.752,1556582400,1556668799 +2019-04-29,5314.317,1556496000,1556582399 +2019-04-28,5299.894,1556409600,1556495999 +2019-04-27,5289.249,1556323200,1556409599 +2019-04-26,5293.450,1556236800,1556323199 +2019-04-25,5512.737,1556150400,1556236799 +2019-04-24,5623.159,1556064000,1556150399 +2019-04-23,5529.134,1555977600,1556063999 +2019-04-22,5392.963,1555891200,1555977599 +2019-04-21,5373.583,1555804800,1555891199 +2019-04-20,5345.772,1555718400,1555804799 +2019-04-19,5328.760,1555632000,1555718399 +2019-04-18,5301.050,1555545600,1555631999 +2019-04-17,5292.088,1555459200,1555545599 +2019-04-16,5197.817,1555372800,1555459199 +2019-04-15,5211.133,1555286400,1555372799 +2019-04-14,5164.740,1555200000,1555286399 +2019-04-13,5129.218,1555113600,1555199999 +2019-04-12,5095.340,1555027200,1555113599 +2019-04-11,5350.273,1554940800,1555027199 +2019-04-10,5334.083,1554854400,1554940799 +2019-04-09,5300.612,1554768000,1554854399 +2019-04-08,5271.853,1554681600,1554767999 +2019-04-07,5155.264,1554595200,1554681599 +2019-04-06,5120.212,1554508800,1554595199 +2019-04-05,4984.962,1554422400,1554508799 +2019-04-04,5013.513,1554336000,1554422399 +2019-04-03,5082.471,1554249600,1554335999 +2019-04-02,4558.099,1554163200,1554249599 +2019-04-01,4214.374,1554076800,1554163199 +2019-03-31,4188.640,1553990400,1554076799 +2019-03-30,4157.999,1553904000,1553990399 +2019-03-29,4102.331,1553817600,1553903999 +2019-03-28,4072.655,1553731200,1553817599 +2019-03-27,4026.635,1553644800,1553731199 +2019-03-26,3977.725,1553558400,1553644799 +2019-03-25,4031.081,1553472000,1553558399 +2019-03-24,4056.992,1553385600,1553471999 +2019-03-23,4031.773,1553299200,1553385599 +2019-03-22,4026.648,1553212800,1553299199 +2019-03-21,4086.487,1553126400,1553212799 +2019-03-20,4057.503,1553040000,1553126399 +2019-03-19,4032.762,1552953600,1553039999 +2019-03-18,4027.446,1552867200,1552953599 +2019-03-17,4029.844,1552780800,1552867199 +2019-03-16,3995.552,1552694400,1552780799 +2019-03-15,3922.327,1552608000,1552694399 +2019-03-14,3910.423,1552521600,1552607999 +2019-03-13,3909.103,1552435200,1552521599 +2019-03-12,3903.727,1552348800,1552435199 +2019-03-11,3906.286,1552262400,1552348799 +2019-03-10,3932.190,1552176000,1552262399 +2019-03-09,3907.367,1552089600,1552175999 +2019-03-08,3901.930,1552003200,1552089599 +2019-03-07,3892.569,1551916800,1552003199 +2019-03-06,3870.730,1551830400,1551916799 +2019-03-05,3821.858,1551744000,1551830399 +2019-03-04,3899.555,1551657600,1551743999 +2019-03-03,3871.789,1551571200,1551657599 +2019-03-02,3847.372,1551484800,1551571199 +2019-03-01,3853.050,1551398400,1551484799 +2019-02-28,3862.966,1551312000,1551398399 +2019-02-27,3856.104,1551225600,1551311999 +2019-02-26,3868.349,1551139200,1551225599 +2019-02-25,3850.464,1551052800,1551139199 +2019-02-24,4147.794,1550966400,1551052799 +2019-02-23,4055.766,1550880000,1550966399 +2019-02-22,3934.754,1550793600,1550879999 +2019-02-21,3937.216,1550707200,1550793599 +2019-02-20,3922.898,1550620800,1550707199 +2019-02-19,3908.779,1550534400,1550620799 +2019-02-18,3759.909,1550448000,1550534399 +2019-02-17,3617.961,1550361600,1550447999 +2019-02-16,3628.274,1550275200,1550361599 +2019-02-15,3601.525,1550188800,1550275199 +2019-02-14,3600.131,1550102400,1550188799 +2019-02-13,3619.024,1550016000,1550102399 +2019-02-12,3621.905,1549929600,1550015999 +2019-02-11,3666.347,1549843200,1549929599 +2019-02-10,3656.453,1549756800,1549843199 +2019-02-09,3642.706,1549670400,1549756799 +2019-02-08,3543.690,1549584000,1549670399 +2019-02-07,3415.546,1549497600,1549583999 +2019-02-06,3464.376,1549411200,1549497599 +2019-02-05,3462.199,1549324800,1549411199 +2019-02-04,3480.533,1549238400,1549324799 +2019-02-03,3498.741,1549152000,1549238399 +2019-02-02,3486.674,1549065600,1549151999 +2019-02-01,3462.648,1548979200,1549065599 +2019-01-31,3479.244,1548892800,1548979199 +2019-01-30,3459.125,1548806400,1548892799 +2019-01-29,3463.890,1548720000,1548806399 +2019-01-28,3574.356,1548633600,1548719999 +2019-01-27,3600.374,1548547200,1548633599 +2019-01-26,3620.290,1548460800,1548547199 +2019-01-25,3607.067,1548374400,1548460799 +2019-01-24,3610.101,1548288000,1548374399 +2019-01-23,3618.392,1548201600,1548287999 +2019-01-22,3588.173,1548115200,1548201599 +2019-01-21,3615.075,1548028800,1548115199 +2019-01-20,3739.207,1547942400,1548028799 +2019-01-19,3709.578,1547856000,1547942399 +2019-01-18,3684.366,1547769600,1547855999 +2019-01-17,3670.839,1547683200,1547769599 +2019-01-16,3673.612,1547596800,1547683199 +2019-01-15,3712.805,1547510400,1547596799 +2019-01-14,3641.984,1547424000,1547510399 +2019-01-13,3672.173,1547337600,1547423999 +2019-01-12,3693.892,1547251200,1547337599 +2019-01-11,3692.248,1547164800,1547251199 +2019-01-10,4047.837,1547078400,1547164799 +2019-01-09,4048.815,1546992000,1547078399 +2019-01-08,4074.970,1546905600,1546991999 +2019-01-07,4092.896,1546819200,1546905599 +2019-01-06,3986.410,1546732800,1546819199 +2019-01-05,3902.834,1546646400,1546732799 +2019-01-04,3867.655,1546560000,1546646399 +2019-01-03,3935.381,1546473600,1546559999 +2019-01-02,3898.504,1546387200,1546473599 +2019-01-01,3802.475,1546300800,1546387199 +2018-12-31,3864.638,1546214400,1546300799 +2018-12-30,3843.425,1546128000,1546214399 +2018-12-29,3930.451,1546041600,1546127999 +2018-12-28,3786.911,1545955200,1546041599 +2018-12-27,3844.044,1545868800,1545955199 +2018-12-26,3837.250,1545782400,1545868799 +2018-12-25,4053.076,1545696000,1545782399 +2018-12-24,4096.497,1545609600,1545695999 +2018-12-23,4027.095,1545523200,1545609599 +2018-12-22,3928.155,1545436800,1545523199 +2018-12-21,4142.046,1545350400,1545436799 +2018-12-20,3933.467,1545264000,1545350399 +2018-12-19,3791.440,1545177600,1545263999 +2018-12-18,3595.368,1545091200,1545177599 +2018-12-17,3418.333,1545004800,1545091199 +2018-12-16,3273.732,1544918400,1545004799 +2018-12-15,3254.760,1544832000,1544918399 +2018-12-14,3324.990,1544745600,1544831999 +2018-12-13,3478.107,1544659200,1544745599 +2018-12-12,3456.392,1544572800,1544659199 +2018-12-11,3469.071,1544486400,1544572799 +2018-12-10,3602.101,1544400000,1544486399 +2018-12-09,3563.395,1544313600,1544399999 +2018-12-08,3464.123,1544227200,1544313599 +2018-12-07,3524.904,1544140800,1544227199 +2018-12-06,3826.506,1544054400,1544140799 +2018-12-05,3969.651,1543968000,1544054399 +2018-12-04,3992.754,1543881600,1543967999 +2018-12-03,4156.734,1543795200,1543881599 +2018-12-02,4248.956,1543708800,1543795199 +2018-12-01,4162.174,1543622400,1543708799 +2018-11-30,4317.791,1543536000,1543622399 +2018-11-29,4342.503,1543449600,1543535999 +2018-11-28,4107.784,1543363200,1543449599 +2018-11-27,3836.933,1543276800,1543363199 +2018-11-26,4042.961,1543190400,1543276799 +2018-11-25,3998.256,1543104000,1543190399 +2018-11-24,4403.166,1543017600,1543103999 +2018-11-23,4377.105,1542931200,1543017599 +2018-11-22,4622.712,1542844800,1542931199 +2018-11-21,4612.678,1542758400,1542844799 +2018-11-20,4921.060,1542672000,1542758399 +2018-11-19,5652.292,1542585600,1542671999 +2018-11-18,5654.226,1542499200,1542585599 +2018-11-17,5636.080,1542412800,1542499199 +2018-11-16,5664.561,1542326400,1542412799 +2018-11-15,5791.214,1542240000,1542326399 +2018-11-14,6371.978,1542153600,1542239999 +2018-11-13,6381.646,1542067200,1542153599 +2018-11-12,6421.550,1541980800,1542067199 +2018-11-11,6409.832,1541894400,1541980799 +2018-11-10,6409.757,1541808000,1541894399 +2018-11-09,6474.937,1541721600,1541807999 +2018-11-08,6536.006,1541635200,1541721599 +2018-11-07,6492.275,1541548800,1541635199 +2018-11-06,6425.584,1541462400,1541548799 +2018-11-05,6459.506,1541376000,1541462399 +2018-11-04,6435.068,1541289600,1541375999 +2018-11-03,6408.476,1541203200,1541289599 +2018-11-02,6406.013,1541116800,1541203199 +2018-11-01,6348.064,1541030400,1541116799 +2018-10-31,6303.637,1540944000,1541030399 +2018-10-30,6279.596,1540857600,1540943999 +2018-10-29,6406.959,1540771200,1540857599 +2018-10-28,6440.621,1540684800,1540771199 +2018-10-27,6424.496,1540598400,1540684799 +2018-10-26,6423.905,1540512000,1540598399 +2018-10-25,6436.944,1540425600,1540511999 +2018-10-24,6456.852,1540339200,1540425599 +2018-10-23,6470.171,1540252800,1540339199 +2018-10-22,6485.758,1540166400,1540252799 +2018-10-21,6485.829,1540080000,1540166399 +2018-10-20,6464.650,1539993600,1540079999 +2018-10-19,6487.650,1539907200,1539993599 +2018-10-18,6530.686,1539820800,1539907199 +2018-10-17,6567.412,1539734400,1539820799 +2018-10-16,6612.678,1539648000,1539734399 +2018-10-15,6783.042,1539561600,1539647999 +2018-10-14,6352.405,1539475200,1539561599 +2018-10-13,6308.160,1539388800,1539475199 +2018-10-12,6292.383,1539302400,1539388799 +2018-10-11,6597.075,1539216000,1539302399 +2018-10-10,6646.183,1539129600,1539215999 +2018-10-09,6659.673,1539043200,1539129599 +2018-10-08,6641.815,1538956800,1539043199 +2018-10-07,6610.780,1538870400,1538956799 +2018-10-06,6629.116,1538784000,1538870399 +2018-10-05,6612.130,1538697600,1538783999 +2018-10-04,6557.832,1538611200,1538697599 +2018-10-03,6540.046,1538524800,1538611199 +2018-10-02,6603.108,1538438400,1538524799 +2018-10-01,6638.531,1538352000,1538438399 +2018-09-30,6618.930,1538265600,1538351999 +2018-09-29,6639.134,1538179200,1538265599 +2018-09-28,6730.329,1538092800,1538179199 +2018-09-27,6590.940,1538006400,1538092799 +2018-09-26,6498.594,1537920000,1538006399 +2018-09-25,6588.875,1537833600,1537919999 +2018-09-24,6717.120,1537747200,1537833599 +2018-09-23,6739.731,1537660800,1537747199 +2018-09-22,6769.349,1537574400,1537660799 +2018-09-21,6622.779,1537488000,1537574399 +2018-09-20,6456.871,1537401600,1537487999 +2018-09-19,6424.687,1537315200,1537401599 +2018-09-18,6333.881,1537228800,1537315199 +2018-09-17,6526.536,1537142400,1537228799 +2018-09-16,6535.007,1537056000,1537142399 +2018-09-15,6533.838,1536969600,1537055999 +2018-09-14,6541.745,1536883200,1536969599 +2018-09-13,6443.937,1536796800,1536883199 +2018-09-12,6338.210,1536710400,1536796799 +2018-09-11,6360.232,1536624000,1536710399 +2018-09-10,6319.431,1536537600,1536623999 +2018-09-09,6323.797,1536451200,1536537599 +2018-09-08,6463.690,1536364800,1536451199 +2018-09-07,6539.436,1536278400,1536364799 +2018-09-06,6720.247,1536192000,1536278399 +2018-09-05,7377.824,1536105600,1536191999 +2018-09-04,7333.934,1536019200,1536105599 +2018-09-03,7301.272,1535932800,1536019199 +2018-09-02,7246.359,1535846400,1535932799 +2018-09-01,7125.004,1535760000,1535846399 +2018-08-31,7016.842,1535673600,1535759999 +2018-08-30,7047.665,1535587200,1535673599 +2018-08-29,7099.432,1535500800,1535587199 +2018-08-28,7004.178,1535414400,1535500799 +2018-08-27,6796.609,1535328000,1535414399 +2018-08-26,6752.383,1535241600,1535327999 +2018-08-25,6745.373,1535155200,1535241599 +2018-08-24,6627.797,1535068800,1535155199 +2018-08-23,6462.820,1534982400,1535068799 +2018-08-22,6650.691,1534896000,1534982399 +2018-08-21,6389.598,1534809600,1534895999 +2018-08-20,6521.625,1534723200,1534809599 +2018-08-19,6479.938,1534636800,1534723199 +2018-08-18,6612.821,1534550400,1534636799 +2018-08-17,6463.466,1534464000,1534550399 +2018-08-16,6388.777,1534377600,1534463999 +2018-08-15,6406.142,1534291200,1534377599 +2018-08-14,6287.053,1534204800,1534291199 +2018-08-13,6426.228,1534118400,1534204799 +2018-08-12,6351.472,1534032000,1534118399 +2018-08-11,6319.660,1533945600,1534031999 +2018-08-10,6571.952,1533859200,1533945599 +2018-08-09,6460.792,1533772800,1533859199 +2018-08-08,6736.300,1533686400,1533772799 +2018-08-07,7042.964,1533600000,1533686399 +2018-08-06,7092.476,1533513600,1533599999 +2018-08-05,7049.044,1533427200,1533513599 +2018-08-04,7457.556,1533340800,1533427199 +2018-08-03,7548.458,1533254400,1533340799 +2018-08-02,7643.241,1533168000,1533254399 +2018-08-01,7746.024,1533081600,1533167999 +2018-07-31,8174.642,1532995200,1533081599 +2018-07-30,8227.634,1532908800,1532995199 +2018-07-29,8251.782,1532822400,1532908799 +2018-07-28,8195.893,1532736000,1532822399 +2018-07-27,8093.398,1532649600,1532735999 +2018-07-26,8222.990,1532563200,1532649599 +2018-07-25,8380.001,1532476800,1532563199 +2018-07-24,8032.247,1532390400,1532476799 +2018-07-23,7570.239,1532304000,1532390399 +2018-07-22,7467.110,1532217600,1532303999 +2018-07-21,7370.427,1532131200,1532217599 +2018-07-20,7498.666,1532044800,1532131199 +2018-07-19,7415.059,1531958400,1532044799 +2018-07-18,7410.063,1531872000,1531958399 +2018-07-17,7023.399,1531785600,1531871999 +2018-07-16,6527.303,1531699200,1531785599 +2018-07-15,6315.706,1531612800,1531699199 +2018-07-14,6242.535,1531526400,1531612799 +2018-07-13,6256.138,1531440000,1531526399 +2018-07-12,6372.493,1531353600,1531439999 +2018-07-11,6354.372,1531267200,1531353599 +2018-07-10,6674.029,1531180800,1531267199 +2018-07-09,6729.744,1531094400,1531180799 +2018-07-08,6737.445,1531008000,1531094399 +2018-07-07,6660.355,1530921600,1531007999 +2018-07-06,6564.459,1530835200,1530921599 +2018-07-05,6624.219,1530748800,1530835199 +2018-07-04,6611.856,1530662400,1530748799 +2018-07-03,6620.905,1530576000,1530662399 +2018-07-02,6500.846,1530489600,1530575999 +2018-07-01,6397.395,1530403200,1530489599 +2018-06-30,6279.811,1530316800,1530403199 +2018-06-29,6045.540,1530230400,1530316799 +2018-06-28,6128.537,1530144000,1530230399 +2018-06-27,6140.305,1530057600,1530143999 +2018-06-26,6251.304,1529971200,1530057599 +2018-06-25,6219.569,1529884800,1529971199 +2018-06-24,6184.478,1529798400,1529884799 +2018-06-23,6158.715,1529712000,1529798399 +2018-06-22,6713.723,1529625600,1529711999 +2018-06-21,6752.172,1529539200,1529625599 +2018-06-20,6737.922,1529452800,1529539199 +2018-06-19,6730.103,1529366400,1529452799 +2018-06-18,6592.260,1529280000,1529366399 +2018-06-17,6520.835,1529193600,1529279999 +2018-06-16,6492.024,1529107200,1529193599 +2018-06-15,6651.750,1529020800,1529107199 +2018-06-14,6487.631,1528934400,1529020799 +2018-06-13,6579.729,1528848000,1528934399 +2018-06-12,6856.605,1528761600,1528847999 +2018-06-11,6827.612,1528675200,1528761599 +2018-06-10,7563.601,1528588800,1528675199 +2018-06-09,7641.195,1528502400,1528588799 +2018-06-08,7668.731,1528416000,1528502399 +2018-06-07,7643.897,1528329600,1528415999 +2018-06-06,7628.551,1528243200,1528329599 +2018-06-05,7566.637,1528156800,1528243199 +2018-06-04,7698.360,1528070400,1528156799 +2018-06-03,7647.945,1527984000,1528070399 +2018-06-02,7590.251,1527897600,1527983999 +2018-06-01,7547.292,1527811200,1527897599 +2018-05-31,7499.969,1527724800,1527811199 +2018-05-30,7523.705,1527638400,1527724799 +2018-05-29,7339.374,1527552000,1527638399 +2018-05-28,7404.420,1527465600,1527551999 +2018-05-27,7369.454,1527379200,1527465599 +2018-05-26,7529.334,1527292800,1527379199 +2018-05-25,7623.265,1527206400,1527292799 +2018-05-24,7649.213,1527120000,1527206399 +2018-05-23,8035.765,1527033600,1527119999 +2018-05-22,8398.981,1526947200,1527033599 +2018-05-21,8520.619,1526860800,1526947199 +2018-05-20,8385.435,1526774400,1526860799 +2018-05-19,8287.219,1526688000,1526774399 +2018-05-18,8175.990,1526601600,1526687999 +2018-05-17,8374.983,1526515200,1526601599 +2018-05-16,8508.463,1526428800,1526515199 +2018-05-15,8784.061,1526342400,1526428799 +2018-05-14,8796.140,1526256000,1526342399 +2018-05-13,8621.067,1526169600,1526255999 +2018-05-12,8528.302,1526083200,1526169599 +2018-05-11,9040.789,1525996800,1526083199 +2018-05-10,9353.748,1525910400,1525996799 +2018-05-09,9308.364,1525824000,1525910399 +2018-05-08,9424.496,1525737600,1525823999 +2018-05-07,9676.611,1525651200,1525737599 +2018-05-06,9914.861,1525564800,1525651199 +2018-05-05,9843.390,1525478400,1525564799 +2018-05-04,9774.475,1525392000,1525478399 +2018-05-03,9521.916,1525305600,1525391999 +2018-05-02,9164.558,1525219200,1525305599 +2018-05-01,9253.084,1525132800,1525219199 +2018-04-30,9438.437,1525046400,1525132799 +2018-04-29,9428.525,1524960000,1525046399 +2018-04-28,9174.172,1524873600,1524959999 +2018-04-27,9318.493,1524787200,1524873599 +2018-04-26,9066.735,1524700800,1524787199 +2018-04-25,9717.257,1524614400,1524700799 +2018-04-24,9321.305,1524528000,1524614399 +2018-04-23,8875.781,1524441600,1524527999 +2018-04-22,8925.119,1524355200,1524441599 +2018-04-21,8896.613,1524268800,1524355199 +2018-04-20,8575.802,1524182400,1524268799 +2018-04-19,8211.280,1524096000,1524182399 +2018-04-18,8033.370,1524009600,1524095999 +2018-04-17,8084.437,1523923200,1524009599 +2018-04-16,8325.430,1523836800,1523923199 +2018-04-15,8122.431,1523750400,1523836799 +2018-04-14,7973.580,1523664000,1523750399 +2018-04-13,7972.708,1523577600,1523663999 +2018-04-12,7379.165,1523491200,1523577599 +2018-04-11,6896.141,1523404800,1523491199 +2018-04-10,6829.425,1523318400,1523404799 +2018-04-09,7084.607,1523232000,1523318399 +2018-04-08,6987.530,1523145600,1523231999 +2018-04-07,6839.120,1523059200,1523145599 +2018-04-06,6833.108,1522972800,1523059199 +2018-04-05,6890.081,1522886400,1522972799 +2018-04-04,7454.194,1522800000,1522886399 +2018-04-03,7294.083,1522713600,1522799999 +2018-04-02,6979.331,1522627200,1522713599 +2018-04-01,7007.184,1522540800,1522627199 +2018-03-31,7032.058,1522454400,1522540799 +2018-03-30,7205.335,1522368000,1522454399 +2018-03-29,7961.849,1522281600,1522367999 +2018-03-28,7959.623,1522195200,1522281599 +2018-03-27,8191.329,1522108800,1522195199 +2018-03-26,8488.218,1522022400,1522108799 +2018-03-25,8617.425,1521936000,1522022399 +2018-03-24,8963.076,1521849600,1521935999 +2018-03-23,8796.761,1521763200,1521849599 +2018-03-22,9037.532,1521676800,1521763199 +2018-03-21,9040.470,1521590400,1521676799 +2018-03-20,8832.938,1521504000,1521590399 +2018-03-19,8428.960,1521417600,1521503999 +2018-03-18,8072.571,1521331200,1521417599 +2018-03-17,8310.014,1521244800,1521331199 +2018-03-16,8436.655,1521158400,1521244799 +2018-03-15,8336.859,1521072000,1521158399 +2018-03-14,9279.620,1520985600,1521071999 +2018-03-13,9330.743,1520899200,1520985599 +2018-03-12,9725.469,1520812800,1520899199 +2018-03-11,9280.524,1520726400,1520812799 +2018-03-10,9432.556,1520640000,1520726399 +2018-03-09,9445.770,1520553600,1520639999 +2018-03-08,10055.804,1520467200,1520553599 +2018-03-07,10795.507,1520380800,1520467199 +2018-03-06,11520.402,1520294400,1520380799 +2018-03-05,11562.585,1520208000,1520294399 +2018-03-04,11506.974,1520121600,1520207999 +2018-03-03,11312.803,1520035200,1520121599 +2018-03-02,11039.071,1519948800,1520035199 +2018-03-01,10699.149,1519862400,1519948799 +2018-02-28,10906.680,1519776000,1519862399 +2018-02-27,10651.089,1519689600,1519775999 +2018-02-26,10092.346,1519603200,1519689599 +2018-02-25,9901.324,1519516800,1519603199 +2018-02-24,10467.218,1519430400,1519516799 +2018-02-23,10233.246,1519344000,1519430399 +2018-02-22,10863.011,1519257600,1519343999 +2018-02-21,11436.166,1519171200,1519257599 +2018-02-20,11587.190,1519084800,1519171199 +2018-02-19,10893.599,1518998400,1519084799 +2018-02-18,11225.244,1518912000,1518998399 +2018-02-17,10678.874,1518825600,1518911999 +2018-02-16,10183.381,1518739200,1518825599 +2018-02-15,9839.235,1518652800,1518739199 +2018-02-14,9041.620,1518566400,1518652799 +2018-02-13,8896.703,1518480000,1518566399 +2018-02-12,8544.465,1518393600,1518479999 +2018-02-11,8624.258,1518307200,1518393599 +2018-02-10,8888.928,1518220800,1518307199 +2018-02-09,8487.144,1518134400,1518220799 +2018-02-08,8078.621,1518048000,1518134399 +2018-02-07,8108.700,1517961600,1518047999 +2018-02-06,7399.570,1517875200,1517961599 +2018-02-05,8279.344,1517788800,1517875199 +2018-02-04,9274.820,1517702400,1517788799 +2018-02-03,9090.664,1517616000,1517702399 +2018-02-02,9122.959,1517529600,1517615999 +2018-02-01,10301.395,1517443200,1517529599 +2018-01-31,10263.317,1517356800,1517443199 +2018-01-30,11366.085,1517270400,1517356799 +2018-01-29,11851.850,1517184000,1517270399 +2018-01-28,11802.863,1517097600,1517183999 +2018-01-27,11380.833,1517011200,1517097599 +2018-01-26,11436.018,1516924800,1517011199 +2018-01-25,11542.186,1516838400,1516924799 +2018-01-24,10821.591,1516752000,1516838399 +2018-01-23,11126.253,1516665600,1516751999 +2018-01-22,11740.070,1516579200,1516665599 +2018-01-21,12982.921,1516492800,1516579199 +2018-01-20,12527.155,1516406400,1516492799 +2018-01-19,11674.677,1516320000,1516406399 +2018-01-18,11775.462,1516233600,1516319999 +2018-01-17,11517.542,1516147200,1516233599 +2018-01-16,14114.073,1516060800,1516147199 +2018-01-15,14358.828,1515974400,1516060799 +2018-01-14,14598.229,1515888000,1515974399 +2018-01-13,14437.355,1515801600,1515887999 +2018-01-12,13968.375,1515715200,1515801599 +2018-01-11,15136.824,1515628800,1515715199 +2018-01-10,14885.185,1515542400,1515628799 +2018-01-09,15672.159,1515456000,1515542399 +2018-01-08,17421.917,1515369600,1515455999 +2018-01-07,17147.576,1515283200,1515369599 +2018-01-06,17102.345,1515196800,1515283199 +2018-01-05,16179.700,1515110400,1515196799 +2018-01-04,15938.841,1515024000,1515110399 +2018-01-03,15270.887,1514937600,1515023999 +2018-01-02,14556.451,1514851200,1514937599 +2018-01-01,14283.984,1514764800,1514851199 +2017-12-31,13447.442,1514678400,1514764799 +2017-12-30,14596.270,1514592000,1514678399 +2017-12-29,14923.615,1514505600,1514591999 +2017-12-28,15671.168,1514419200,1514505599 +2017-12-27,16737.457,1514332800,1514419199 +2017-12-26,15187.797,1514246400,1514332799 +2017-12-25,14266.144,1514160000,1514246399 +2017-12-24,14567.913,1514073600,1514159999 +2017-12-23,14758.510,1513987200,1514073599 +2017-12-22,15746.469,1513900800,1513987199 +2017-12-21,17050.880,1513814400,1513900799 +2017-12-20,17824.755,1513728000,1513814399 +2017-12-19,19078.646,1513641600,1513727999 +2017-12-18,19220.998,1513555200,1513641599 +2017-12-17,19672.523,1513468800,1513555199 +2017-12-16,18649.440,1513382400,1513468799 +2017-12-15,17247.048,1513296000,1513382399 +2017-12-14,16537.949,1513209600,1513295999 +2017-12-13,16878.529,1513123200,1513209599 +2017-12-12,17129.020,1513036800,1513123199 +2017-12-11,16412.018,1512950400,1513036799 +2017-12-10,15536.313,1512864000,1512950399 +2017-12-09,16668.356,1512777600,1512863999 +2017-12-08,18291.161,1512691200,1512777599 +2017-12-07,16067.545,1512604800,1512691199 +2017-12-06,12975.444,1512518400,1512604799 +2017-12-05,11825.221,1512432000,1512518399 +2017-12-04,11482.008,1512345600,1512431999 +2017-12-03,11436.018,1512259200,1512345599 +2017-12-02,11146.876,1512172800,1512259199 +2017-12-01,10620.868,1512086400,1512172799 +2017-11-30,10373.926,1512000000,1512086399 +2017-11-29,10833.875,1511913600,1511999999 +2017-11-28,10020.315,1511827200,1511913599 +2017-11-27,9611.228,1511740800,1511827199 +2017-11-26,9172.035,1511654400,1511740799 +2017-11-25,8542.643,1511568000,1511654399 +2017-11-24,8224.981,1511481600,1511567999 +2017-11-23,8243.607,1511395200,1511481599 +2017-11-22,8205.142,1511308800,1511395199 +2017-11-21,8271.862,1511222400,1511308799 +2017-11-20,8137.714,1511136000,1511222399 +2017-11-19,7909.195,1511049600,1511135999 +2017-11-18,7774.997,1510963200,1511049599 +2017-11-17,7934.559,1510876800,1510963199 +2017-11-16,7643.518,1510790400,1510876799 +2017-11-15,7004.954,1510704000,1510790399 +2017-11-14,6681.070,1510617600,1510703999 +2017-11-13,6420.121,1510531200,1510617599 +2017-11-12,6418.156,1510444800,1510531199 +2017-11-11,6730.203,1510358400,1510444799 +2017-11-10,7279.531,1510272000,1510358399 +2017-11-09,7470.069,1510185600,1510271999 +2017-11-08,7446.915,1510099200,1510185599 +2017-11-07,7163.162,1510012800,1510099199 +2017-11-06,7431.934,1509926400,1510012799 +2017-11-05,7506.450,1509840000,1509926399 +2017-11-04,7342.259,1509753600,1509839999 +2017-11-03,7260.751,1509667200,1509753599 +2017-11-02,7108.706,1509580800,1509667199 +2017-11-01,6592.334,1509494400,1509580799 +2017-10-31,6261.213,1509408000,1509494399 +2017-10-30,6146.278,1509321600,1509407999 +2017-10-29,5983.044,1509235200,1509321599 +2017-10-28,5806.141,1509148800,1509235199 +2017-10-27,5940.262,1509062400,1509148799 +2017-10-26,5838.078,1508976000,1509062399 +2017-10-25,5627.612,1508889600,1508975999 +2017-10-24,5929.837,1508803200,1508889599 +2017-10-23,6042.058,1508716800,1508803199 +2017-10-22,6059.693,1508630400,1508716799 +2017-10-21,6089.344,1508544000,1508630399 +2017-10-20,5853.920,1508457600,1508543999 +2017-10-19,5649.943,1508371200,1508457599 +2017-10-18,5611.878,1508284800,1508371199 +2017-10-17,5727.784,1508198400,1508284799 +2017-10-16,5715.737,1508112000,1508198399 +2017-10-15,5822.078,1508025600,1508111999 +2017-10-14,5727.420,1507939200,1508025599 +2017-10-13,5650.986,1507852800,1507939199 +2017-10-12,5136.366,1507766400,1507852799 +2017-10-11,4858.448,1507680000,1507766399 +2017-10-10,4848.724,1507593600,1507679999 +2017-10-09,4731.316,1507507200,1507593599 +2017-10-08,4502.832,1507420800,1507507199 +2017-10-07,4381.611,1507334400,1507420799 +2017-10-06,4350.346,1507248000,1507334399 +2017-10-05,4292.953,1507161600,1507247999 +2017-10-04,4324.895,1507075200,1507161599 +2017-10-03,4422.184,1506988800,1507075199 +2017-10-02,4404.441,1506902400,1506988799 +2017-10-01,4340.526,1506816000,1506902399 +2017-09-30,4224.632,1506729600,1506815999 +2017-09-29,4183.725,1506643200,1506729599 +2017-09-28,4239.990,1506556800,1506643199 +2017-09-27,4051.200,1506470400,1506556799 +2017-09-26,3947.980,1506384000,1506470399 +2017-09-25,3816.545,1506297600,1506383999 +2017-09-24,3794.275,1506211200,1506297599 +2017-09-23,3724.955,1506124800,1506211199 +2017-09-22,3694.655,1506038400,1506124799 +2017-09-21,3911.185,1505952000,1506038399 +2017-09-20,3978.180,1505865600,1505951999 +2017-09-19,4079.635,1505779200,1505865599 +2017-09-18,3831.055,1505692800,1505779199 +2017-09-17,3644.925,1505606400,1505692799 +2017-09-16,3723.180,1505520000,1505606399 +2017-09-15,3444.200,1505433600,1505519999 +2017-09-14,3901.595,1505347200,1505433599 +2017-09-13,4131.395,1505260800,1505347199 +2017-09-12,4252.960,1505174400,1505260799 +2017-09-11,4192.305,1505088000,1505174399 +2017-09-10,4235.750,1505001600,1505087999 +2017-09-09,4268.785,1504915200,1505001599 +2017-09-08,4630.440,1504828800,1504915199 +2017-09-07,4626.080,1504742400,1504828799 +2017-09-06,4496.890,1504656000,1504742399 +2017-09-05,4332.075,1504569600,1504655999 +2017-09-04,4587.295,1504483200,1504569599 +2017-09-03,4646.425,1504396800,1504483199 +2017-09-02,4933.525,1504310400,1504396799 +2017-09-01,4795.060,1504224000,1504310399 +2017-08-31,4650.675,1504137600,1504223999 +2017-08-30,4602.770,1504051200,1504137599 +2017-08-29,4504.170,1503964800,1504051199 +2017-08-28,4393.405,1503878400,1503964799 +2017-08-27,4384.495,1503792000,1503878399 +2017-08-26,4375.440,1503705600,1503791999 +2017-08-25,4395.190,1503619200,1503705599 +2017-08-24,4263.955,1503532800,1503619199 +2017-08-23,4178.150,1503446400,1503532799 +2017-08-22,4065.250,1503360000,1503446399 +2017-08-21,4098.400,1503273600,1503359999 +2017-08-20,4194.995,1503187200,1503273599 +2017-08-19,4201.940,1503100800,1503187199 +2017-08-18,4350.910,1503014400,1503100799 +2017-08-17,4430.665,1502928000,1503014399 +2017-08-16,4281.580,1502841600,1502927999 +2017-08-15,4390.550,1502755200,1502841599 +2017-08-14,4198.480,1502668800,1502755199 +2017-08-13,4046.550,1502582400,1502668799 +2017-08-12,3800.270,1502496000,1502582399 +2017-08-11,3530.500,1502409600,1502495999 +2017-08-10,3397.960,1502323200,1502409599 +2017-08-09,3421.350,1502236800,1502323199 +2017-08-08,3431.895,1502150400,1502236799 +2017-08-07,3305.810,1502064000,1502150399 +2017-08-06,3273.100,1501977600,1502063999 +2017-08-05,3092.950,1501891200,1501977599 +2017-08-04,2852.030,1501804800,1501891199 +2017-08-03,2761.990,1501718400,1501804799 +2017-08-02,2740.395,1501632000,1501718399 +2017-08-01,2898.345,1501545600,1501631999 +2017-07-31,2823.400,1501459200,1501545599 +2017-07-30,2742.490,1501372800,1501459199 +2017-07-29,2807.890,1501286400,1501372799 +2017-07-28,2784.615,1501200000,1501286399 +2017-07-27,2611.385,1501113600,1501199999 +2017-07-26,2593.620,1501027200,1501113599 +2017-07-25,2761.470,1500940800,1501027199 +2017-07-24,2753.830,1500854400,1500940799 +2017-07-23,2821.150,1500768000,1500854399 +2017-07-22,2765.090,1500681600,1500767999 +2017-07-21,2828.005,1500595200,1500681599 +2017-07-20,2587.065,1500508800,1500595199 +2017-07-19,2358.025,1500422400,1500508799 +2017-07-18,2308.010,1500336000,1500422399 +2017-07-17,2080.155,1500249600,1500335999 +2017-07-16,2028.815,1500163200,1500249599 +2017-07-15,2233.340,1500076800,1500163199 +2017-07-14,2360.575,1499990400,1500076799 +2017-07-13,2412.030,1499904000,1499990399 +2017-07-12,2380.750,1499817600,1499903999 +2017-07-11,2393.015,1499731200,1499817599 +2017-07-10,2527.800,1499644800,1499731199 +2017-07-09,2603.415,1499558400,1499644799 +2017-07-08,2544.250,1499472000,1499558399 +2017-07-07,2762.350,1499385600,1499471999 +2017-07-06,2609.355,1499299200,1499385599 +2017-07-05,2612.145,1499212800,1499299199 +2017-07-04,2597.825,1499126400,1499212799 +2017-07-03,2550.735,1499040000,1499126399 +2017-07-02,2474.415,1498953600,1499039999 +2017-07-01,2498.055,1498867200,1498953599 +2017-06-30,2549.285,1498780800,1498867199 +2017-06-29,2581.810,1498694400,1498780799 +2017-06-28,2578.215,1498608000,1498694399 +2017-06-27,2507.490,1498521600,1498607999 +2017-06-26,2602.330,1498435200,1498521599 +2017-06-25,2645.490,1498348800,1498435199 +2017-06-24,2751.425,1498262400,1498348799 +2017-06-23,2735.290,1498176000,1498262399 +2017-06-22,2706.420,1498089600,1498175999 +2017-06-21,2746.900,1498003200,1498089599 +2017-06-20,2676.525,1497916800,1498003199 +2017-06-19,2579.295,1497830400,1497916799 +2017-06-18,2658.990,1497744000,1497830399 +2017-06-17,2601.875,1497657600,1497743999 +2017-06-16,2502.250,1497571200,1497657599 +2017-06-15,2520.540,1497484800,1497571199 +2017-06-14,2751.925,1497398400,1497484799 +2017-06-13,2724.335,1497312000,1497398399 +2017-06-12,2977.685,1497225600,1497311999 +2017-06-11,2972.155,1497139200,1497225599 +2017-06-10,2887.400,1497052800,1497139199 +2017-06-09,2853.665,1496966400,1497052799 +2017-06-08,2773.730,1496880000,1496966399 +2017-06-07,2866.290,1496793600,1496879999 +2017-06-06,2843.360,1496707200,1496793599 +2017-06-05,2596.890,1496620800,1496707199 +2017-06-04,2550.620,1496534400,1496620799 +2017-06-03,2535.230,1496448000,1496534399 +2017-06-02,2446.250,1496361600,1496447999 +2017-06-01,2367.400,1496275200,1496361599 +2017-05-31,2243.275,1496188800,1496275199 +2017-05-30,2278.785,1496102400,1496188799 +2017-05-29,2231.425,1496016000,1496102399 +2017-05-28,2153.105,1495929600,1496015999 +2017-05-27,2231.310,1495843200,1495929599 +2017-05-26,2439.385,1495756800,1495843199 +2017-05-25,2603.675,1495670400,1495756799 +2017-05-24,2422.070,1495584000,1495670399 +2017-05-23,2247.110,1495497600,1495583999 +2017-05-22,2172.550,1495411200,1495497599 +2017-05-21,2101.905,1495324800,1495411199 +2017-05-20,2035.185,1495238400,1495324799 +2017-05-19,1946.585,1495152000,1495238399 +2017-05-18,1871.785,1495065600,1495151999 +2017-05-17,1799.250,1494979200,1495065599 +2017-05-16,1762.185,1494892800,1494979199 +2017-05-15,1810.855,1494806400,1494892799 +2017-05-14,1818.165,1494720000,1494806399 +2017-05-13,1768.615,1494633600,1494719999 +2017-05-12,1852.360,1494547200,1494633599 +2017-05-11,1830.530,1494460800,1494547199 +2017-05-10,1771.900,1494374400,1494460799 +2017-05-09,1778.420,1494288000,1494374399 +2017-05-08,1659.870,1494201600,1494287999 +2017-05-07,1587.760,1494115200,1494201599 +2017-05-06,1567.075,1494028800,1494115199 +2017-05-05,1577.850,1493942400,1494028799 +2017-05-04,1549.500,1493856000,1493942399 +2017-05-03,1472.795,1493769600,1493855999 +2017-05-02,1447.750,1493683200,1493769599 +2017-05-01,1391.105,1493596800,1493683199 +2017-04-30,1334.850,1493510400,1493596799 +2017-04-29,1321.840,1493424000,1493510399 +2017-04-28,1324.505,1493337600,1493423999 +2017-04-27,1300.390,1493251200,1493337599 +2017-04-26,1280.160,1493164800,1493251199 +2017-04-25,1258.865,1493078400,1493164799 +2017-04-24,1229.075,1492992000,1493078399 +2017-04-23,1231.955,1492905600,1492991999 +2017-04-22,1228.805,1492819200,1492905599 +2017-04-21,1232.510,1492732800,1492819199 +2017-04-20,1225.540,1492646400,1492732799 +2017-04-19,1213.590,1492560000,1492646399 +2017-04-18,1205.740,1492473600,1492559999 +2017-04-17,1188.920,1492387200,1492473599 +2017-04-16,1179.870,1492300800,1492387199 +2017-04-15,1177.770,1492214400,1492300799 +2017-04-14,1180.040,1492128000,1492214399 +2017-04-13,1203.130,1492041600,1492127999 +2017-04-12,1206.075,1491955200,1492041599 +2017-04-11,1197.600,1491868800,1491955199 +2017-04-10,1189.105,1491782400,1491868799 +2017-04-09,1186.580,1491696000,1491782399 +2017-04-08,1180.940,1491609600,1491695999 +2017-04-07,1184.630,1491523200,1491609599 +2017-04-06,1156.575,1491436800,1491523199 +2017-04-05,1134.170,1491350400,1491436799 +2017-04-04,1150.125,1491264000,1491350399 +2017-04-03,1126.955,1491177600,1491263999 +2017-04-02,1094.045,1491091200,1491177599 +2017-04-01,1081.755,1491004800,1491091199 +2017-03-31,1050.675,1490918400,1491004799 +2017-03-30,1044.630,1490832000,1490918399 +2017-03-29,1051.140,1490745600,1490831999 +2017-03-28,1055.210,1490659200,1490745599 +2017-03-27,1006.563,1490572800,1490659199 +2017-03-26,990.370,1490486400,1490572799 +2017-03-25,956.641,1490400000,1490486399 +2017-03-24,1039.530,1490313600,1490399999 +2017-03-23,1053.575,1490227200,1490313599 +2017-03-22,1120.595,1490140800,1490227199 +2017-03-21,1088.330,1490054400,1490140799 +2017-03-20,1049.885,1489968000,1490054399 +2017-03-19,1021.864,1489881600,1489967999 +2017-03-18,1107.150,1489795200,1489881599 +2017-03-17,1187.810,1489708800,1489795199 +2017-03-16,1253.795,1489622400,1489708799 +2017-03-15,1245.805,1489536000,1489622399 +2017-03-14,1238.365,1489449600,1489535999 +2017-03-13,1229.375,1489363200,1489449599 +2017-03-12,1201.405,1489276800,1489363199 +2017-03-11,1155.275,1489190400,1489276799 +2017-03-10,1229.480,1489104000,1489190399 +2017-03-09,1173.730,1489017600,1489103999 +2017-03-08,1227.850,1488931200,1489017599 +2017-03-07,1274.190,1488844800,1488931199 +2017-03-06,1271.560,1488758400,1488844799 +2017-03-05,1261.220,1488672000,1488758399 +2017-03-04,1277.195,1488585600,1488671999 +2017-03-03,1265.660,1488499200,1488585599 +2017-03-02,1241.700,1488412800,1488499199 +2017-03-01,1200.695,1488326400,1488412799 +2017-02-28,1186.610,1488240000,1488326399 +2017-02-27,1173.590,1488153600,1488239999 +2017-02-26,1155.655,1488067200,1488153599 +2017-02-25,1174.265,1487980800,1488067199 +2017-02-24,1183.555,1487894400,1487980799 +2017-02-23,1147.030,1487808000,1487894399 +2017-02-22,1120.345,1487721600,1487807999 +2017-02-21,1098.615,1487635200,1487721599 +2017-02-20,1064.180,1487548800,1487635199 +2017-02-19,1055.615,1487462400,1487548799 +2017-02-18,1053.655,1487376000,1487462399 +2017-02-17,1040.305,1487289600,1487375999 +2017-02-16,1020.425,1487203200,1487289599 +2017-02-15,1006.695,1487116800,1487203199 +2017-02-14,1001.076,1487030400,1487116799 +2017-02-13,1000.641,1486944000,1487030399 +2017-02-12,1004.605,1486857600,1486943999 +2017-02-11,998.982,1486771200,1486857599 +2017-02-10,996.644,1486684800,1486771199 +2017-02-09,1076.030,1486598400,1486684799 +2017-02-08,1070.160,1486512000,1486598399 +2017-02-07,1050.040,1486425600,1486511999 +2017-02-06,1035.990,1486339200,1486425599 +2017-02-05,1043.265,1486252800,1486339199 +2017-02-04,1037.905,1486166400,1486252799 +2017-02-03,1022.835,1486080000,1486166399 +2017-02-02,1001.272,1485993600,1486079999 +2017-02-01,979.759,1485907200,1485993599 +2017-01-31,946.201,1485820800,1485907199 +2017-01-30,921.272,1485734400,1485820799 +2017-01-29,922.504,1485648000,1485734399 +2017-01-28,921.831,1485561600,1485647999 +2017-01-27,920.405,1485475200,1485561599 +2017-01-26,910.434,1485388800,1485475199 +2017-01-25,897.970,1485302400,1485388799 +2017-01-24,922.579,1485216000,1485302399 +2017-01-23,926.470,1485129600,1485215999 +2017-01-22,929.657,1485043200,1485129599 +2017-01-21,911.197,1484956800,1485043199 +2017-01-20,899.236,1484870400,1484956799 +2017-01-19,895.616,1484784000,1484870399 +2017-01-18,912.719,1484697600,1484783999 +2017-01-17,871.048,1484611200,1484697599 +2017-01-16,828.164,1484524800,1484611199 +2017-01-15,820.860,1484438400,1484524799 +2017-01-14,829.535,1484352000,1484438399 +2017-01-13,816.918,1484265600,1484351999 +2017-01-12,802.002,1484179200,1484265599 +2017-01-11,913.564,1484092800,1484179199 +2017-01-10,908.851,1484006400,1484092799 +2017-01-09,912.443,1483920000,1484006399 +2017-01-08,925.655,1483833600,1483919999 +2017-01-07,906.030,1483747200,1483833599 +2017-01-06,1030.095,1483660800,1483747199 +2017-01-05,1172.915,1483574400,1483660799 +2017-01-04,1101.630,1483488000,1483574399 +2017-01-03,1032.915,1483401600,1483487999 +2017-01-02,1014.858,1483315200,1483401599 +2017-01-01,983.412,1483228800,1483315199 +2016-12-31,962.419,1483142400,1483228799 +2016-12-30,973.497,1483056000,1483142399 +2016-12-29,977.659,1482969600,1483055999 +2016-12-28,954.490,1482883200,1482969599 +2016-12-27,923.829,1482796800,1482883199 +2016-12-26,904.684,1482710400,1482796799 +2016-12-25,899.237,1482624000,1482710399 +2016-12-24,922.732,1482537600,1482623999 +2016-12-23,894.829,1482451200,1482537599 +2016-12-22,855.032,1482364800,1482451199 +2016-12-21,816.471,1482278400,1482364799 +2016-12-20,797.026,1482192000,1482278399 +2016-12-19,792.071,1482105600,1482191999 +2016-12-18,792.783,1482019200,1482105599 +2016-12-17,788.708,1481932800,1482019199 +2016-12-16,781.560,1481846400,1481932799 +2016-12-15,781.481,1481760000,1481846399 +2016-12-14,781.295,1481673600,1481759999 +2016-12-13,784.274,1481587200,1481673599 +2016-12-12,775.827,1481500800,1481587199 +2016-12-11,774.724,1481414400,1481500799 +2016-12-10,774.943,1481328000,1481414399 +2016-12-09,772.669,1481241600,1481327999 +2016-12-08,771.415,1481155200,1481241599 +2016-12-07,767.884,1481068800,1481155199 +2016-12-06,762.161,1480982400,1481068799 +2016-12-05,773.872,1480896000,1480982399 +2016-12-04,772.338,1480809600,1480895999 +2016-12-03,778.096,1480723200,1480809599 +2016-12-02,769.035,1480636800,1480723199 +2016-12-01,751.983,1480550400,1480636799 +2016-11-30,741.767,1480464000,1480550399 +2016-11-29,736.642,1480377600,1480463999 +2016-11-28,735.021,1480291200,1480377599 +2016-11-27,737.200,1480204800,1480291199 +2016-11-26,741.932,1480118400,1480204799 +2016-11-25,740.953,1480032000,1480118399 +2016-11-24,745.713,1479945600,1480031999 +2016-11-23,751.799,1479859200,1479945599 +2016-11-22,746.559,1479772800,1479859199 +2016-11-21,736.374,1479686400,1479772799 +2016-11-20,753.548,1479600000,1479686399 +2016-11-19,753.911,1479513600,1479599999 +2016-11-18,746.930,1479427200,1479513599 +2016-11-17,749.922,1479340800,1479427199 +2016-11-16,729.391,1479254400,1479340799 +2016-11-15,710.370,1479168000,1479254399 +2016-11-14,704.158,1479081600,1479167999 +2016-11-13,705.156,1478995200,1479081599 +2016-11-12,716.780,1478908800,1478995199 +2016-11-11,716.926,1478822400,1478908799 +2016-11-10,723.273,1478736000,1478822399 +2016-11-09,724.947,1478649600,1478735999 +2016-11-08,708.059,1478563200,1478649599 +2016-11-07,711.522,1478476800,1478563199 +2016-11-06,708.838,1478390400,1478476799 +2016-11-05,705.373,1478304000,1478390399 +2016-11-04,697.815,1478217600,1478303999 +2016-11-03,743.301,1478131200,1478217599 +2016-11-02,734.488,1478044800,1478131199 +2016-11-01,718.712,1477958400,1478044799 +2016-10-31,705.577,1477872000,1477958399 +2016-10-30,714.479,1477785600,1477871999 +2016-10-29,705.027,1477699200,1477785599 +2016-10-28,689.379,1477612800,1477699199 +2016-10-27,683.449,1477526400,1477612799 +2016-10-26,668.658,1477440000,1477526399 +2016-10-25,659.093,1477353600,1477439999 +2016-10-24,657.162,1477267200,1477353599 +2016-10-23,659.212,1477180800,1477267199 +2016-10-22,645.513,1477094400,1477180799 +2016-10-21,632.476,1477008000,1477094399 +2016-10-20,631.219,1476921600,1477007999 +2016-10-19,638.417,1476835200,1476921599 +2016-10-18,639.965,1476748800,1476835199 +2016-10-17,641.980,1476662400,1476748799 +2016-10-16,640.772,1476576000,1476662399 +2016-10-15,641.240,1476489600,1476575999 +2016-10-14,639.036,1476403200,1476489599 +2016-10-13,637.513,1476316800,1476403199 +2016-10-12,641.205,1476230400,1476316799 +2016-10-11,630.537,1476144000,1476230399 +2016-10-10,619.035,1476057600,1476143999 +2016-10-09,619.153,1475971200,1476057599 +2016-10-08,618.485,1475884800,1475971199 +2016-10-07,615.467,1475798400,1475884799 +2016-10-06,613.165,1475712000,1475798399 +2016-10-05,612.009,1475625600,1475711999 +2016-10-04,612.133,1475539200,1475625599 +2016-10-03,611.730,1475452800,1475539199 +2016-10-02,613.994,1475366400,1475452799 +2016-10-01,612.486,1475280000,1475366399 +2016-09-30,607.682,1475193600,1475279999 +2016-09-29,605.776,1475107200,1475193599 +2016-09-28,606.378,1475020800,1475107199 +2016-09-27,608.146,1474934400,1475020799 +2016-09-26,604.485,1474848000,1474934399 +2016-09-25,603.003,1474761600,1474847999 +2016-09-24,603.711,1474675200,1474761599 +2016-09-23,599.752,1474588800,1474675199 +2016-09-22,597.818,1474502400,1474588799 +2016-09-21,608.312,1474416000,1474502399 +2016-09-20,609.376,1474329600,1474415999 +2016-09-19,610.403,1474243200,1474329599 +2016-09-18,608.071,1474156800,1474243199 +2016-09-17,607.417,1474070400,1474156799 +2016-09-16,608.208,1473984000,1474070399 +2016-09-15,610.885,1473897600,1473983999 +2016-09-14,610.597,1473811200,1473897599 +2016-09-13,609.718,1473724800,1473811199 +2016-09-12,607.589,1473638400,1473724799 +2016-09-11,626.164,1473552000,1473638399 +2016-09-10,623.978,1473465600,1473551999 +2016-09-09,626.573,1473379200,1473465599 +2016-09-08,621.657,1473292800,1473379199 +2016-09-07,612.491,1473206400,1473292799 +2016-09-06,608.710,1473120000,1473206399 +2016-09-05,608.845,1473033600,1473119999 +2016-09-04,605.025,1472947200,1473033599 +2016-09-03,587.519,1472860800,1472947199 +2016-09-02,573.973,1472774400,1472860799 +2016-09-01,575.892,1472688000,1472774399 +2016-08-31,577.682,1472601600,1472687999 +2016-08-30,576.232,1472515200,1472601599 +2016-08-29,575.095,1472428800,1472515199 +2016-08-28,571.993,1472342400,1472428799 +2016-08-27,579.748,1472256000,1472342399 +2016-08-26,579.192,1472169600,1472255999 +2016-08-25,580.317,1472083200,1472169599 +2016-08-24,583.503,1471996800,1472083199 +2016-08-23,588.114,1471910400,1471996799 +2016-08-22,584.878,1471824000,1471910399 +2016-08-21,582.928,1471737600,1471823999 +2016-08-20,579.224,1471651200,1471737599 +2016-08-19,576.278,1471564800,1471651199 +2016-08-18,575.504,1471478400,1471564799 +2016-08-17,579.167,1471392000,1471478399 +2016-08-16,574.489,1471305600,1471391999 +2016-08-15,572.027,1471219200,1471305599 +2016-08-14,585.627,1471132800,1471219199 +2016-08-13,588.667,1471046400,1471132799 +2016-08-12,589.515,1470960000,1471046399 +2016-08-11,594.823,1470873600,1470959999 +2016-08-10,593.893,1470787200,1470873599 +2016-08-09,591.073,1470700800,1470787199 +2016-08-08,592.842,1470614400,1470700799 +2016-08-07,592.646,1470528000,1470614399 +2016-08-06,581.720,1470441600,1470527999 +2016-08-05,578.289,1470355200,1470441599 +2016-08-04,572.926,1470268800,1470355199 +2016-08-03,560.413,1470182400,1470268799 +2016-08-02,609.560,1470096000,1470182399 +2016-08-01,625.400,1470009600,1470095999 +2016-07-31,655.166,1469923200,1470009599 +2016-07-30,657.608,1469836800,1469923199 +2016-07-29,656.416,1469750400,1469836799 +2016-07-28,655.974,1469664000,1469750399 +2016-07-27,654.620,1469577600,1469663999 +2016-07-26,655.161,1469491200,1469577599 +2016-07-25,661.557,1469404800,1469491199 +2016-07-24,659.333,1469318400,1469404799 +2016-07-23,653.493,1469232000,1469318399 +2016-07-22,665.798,1469145600,1469231999 +2016-07-21,665.952,1469059200,1469145599 +2016-07-20,672.897,1468972800,1469059199 +2016-07-19,673.192,1468886400,1468972799 +2016-07-18,680.507,1468800000,1468886399 +2016-07-17,671.566,1468713600,1468799999 +2016-07-16,664.858,1468627200,1468713599 +2016-07-15,662.578,1468540800,1468627199 +2016-07-14,658.685,1468454400,1468540799 +2016-07-13,666.626,1468368000,1468454399 +2016-07-12,661.459,1468281600,1468367999 +2016-07-11,654.495,1468195200,1468281599 +2016-07-10,651.627,1468108800,1468195199 +2016-07-09,666.523,1468022400,1468108799 +2016-07-08,653.635,1467936000,1468022399 +2016-07-07,679.882,1467849600,1467935999 +2016-07-06,676.263,1467763200,1467849599 +2016-07-05,683.662,1467676800,1467763199 +2016-07-04,671.007,1467590400,1467676799 +2016-07-03,704.335,1467504000,1467590399 +2016-07-02,689.792,1467417600,1467503999 +2016-07-01,679.746,1467331200,1467417599 +2016-06-30,657.647,1467244800,1467331199 +2016-06-29,644.402,1467158400,1467244799 +2016-06-28,657.262,1467072000,1467158399 +2016-06-27,639.843,1466985600,1467071999 +2016-06-26,665.552,1466899200,1466985599 +2016-06-25,678.515,1466812800,1466899199 +2016-06-24,652.852,1466726400,1466812799 +2016-06-23,612.722,1466640000,1466726399 +2016-06-22,672.661,1466553600,1466639999 +2016-06-21,737.226,1466467200,1466553599 +2016-06-20,763.933,1466380800,1466467199 +2016-06-19,761.424,1466294400,1466380799 +2016-06-18,763.450,1466208000,1466294399 +2016-06-17,770.832,1466121600,1466207999 +2016-06-16,734.096,1466035200,1466121599 +2016-06-15,690.931,1465948800,1466035199 +2016-06-14,704.440,1465862400,1465948799 +2016-06-13,694.394,1465776000,1465862399 +2016-06-12,645.786,1465689600,1465775999 +2016-06-11,592.293,1465603200,1465689599 +2016-06-10,576.879,1465516800,1465603199 +2016-06-09,581.924,1465430400,1465516799 +2016-06-08,579.718,1465344000,1465430399 +2016-06-07,587.898,1465257600,1465343999 +2016-06-06,580.724,1465171200,1465257599 +2016-06-05,577.768,1465084800,1465171199 +2016-06-04,579.663,1464998400,1465084799 +2016-06-03,556.305,1464912000,1464998399 +2016-06-02,538.636,1464825600,1464911999 +2016-06-01,537.233,1464739200,1464825599 +2016-05-31,540.241,1464652800,1464739199 +2016-05-30,535.291,1464566400,1464652799 +2016-05-29,542.000,1464480000,1464566399 +2016-05-28,503.469,1464393600,1464479999 +2016-05-27,465.767,1464307200,1464393599 +2016-05-26,451.622,1464220800,1464307199 +2016-05-25,448.140,1464134400,1464220799 +2016-05-24,445.628,1464048000,1464134399 +2016-05-23,441.834,1463961600,1464047999 +2016-05-22,443.308,1463875200,1463961599 +2016-05-21,443.227,1463788800,1463875199 +2016-05-20,441.385,1463702400,1463788799 +2016-05-19,454.626,1463616000,1463702399 +2016-05-18,454.891,1463529600,1463615999 +2016-05-17,454.618,1463443200,1463529599 +2016-05-16,457.884,1463356800,1463443199 +2016-05-15,457.182,1463270400,1463356799 +2016-05-14,456.253,1463184000,1463270399 +2016-05-13,455.911,1463097600,1463183999 +2016-05-12,453.839,1463011200,1463097599 +2016-05-11,452.736,1462924800,1463011199 +2016-05-10,461.206,1462838400,1462924799 +2016-05-09,460.515,1462752000,1462838399 +2016-05-08,458.977,1462665600,1462751999 +2016-05-07,460.139,1462579200,1462665599 +2016-05-06,454.676,1462492800,1462579199 +2016-05-05,447.614,1462406400,1462492799 +2016-05-04,450.341,1462320000,1462406399 +2016-05-03,447.883,1462233600,1462319999 +2016-05-02,452.160,1462147200,1462233599 +2016-05-01,450.399,1462060800,1462147199 +2016-04-30,455.342,1461974400,1462060799 +2016-04-29,452.198,1461888000,1461974399 +2016-04-28,447.119,1461801600,1461887999 +2016-04-27,466.584,1461715200,1461801599 +2016-04-26,464.696,1461628800,1461715199 +2016-04-25,462.588,1461542400,1461628799 +2016-04-24,455.214,1461456000,1461542399 +2016-04-23,447.980,1461369600,1461455999 +2016-04-22,449.618,1461283200,1461369599 +2016-04-21,445.969,1461196800,1461283199 +2016-04-20,439.282,1461110400,1461196799 +2016-04-19,432.306,1461024000,1461110399 +2016-04-18,428.337,1460937600,1461023999 +2016-04-17,430.972,1460851200,1460937599 +2016-04-16,431.169,1460764800,1460851199 +2016-04-15,427.105,1460678400,1460764799 +2016-04-14,424.553,1460592000,1460678399 +2016-04-13,425.924,1460505600,1460591999 +2016-04-12,424.880,1460419200,1460505599 +2016-04-11,422.152,1460332800,1460419199 +2016-04-10,420.923,1460246400,1460332799 +2016-04-09,420.620,1460160000,1460246399 +2016-04-08,424.053,1460073600,1460159999 +2016-04-07,423.535,1459987200,1460073599 +2016-04-06,424.279,1459900800,1459987199 +2016-04-05,422.851,1459814400,1459900799 +2016-04-04,421.624,1459728000,1459814399 +2016-04-03,421.227,1459641600,1459727999 +2016-04-02,420.021,1459555200,1459641599 +2016-04-01,417.451,1459468800,1459555199 +2016-03-31,416.593,1459382400,1459468799 +2016-03-30,416.675,1459296000,1459382399 +2016-03-29,425.217,1459209600,1459295999 +2016-03-28,426.811,1459123200,1459209599 +2016-03-27,423.371,1459036800,1459123199 +2016-03-26,418.082,1458950400,1459036799 +2016-03-25,417.237,1458864000,1458950399 +2016-03-24,418.361,1458777600,1458863999 +2016-03-23,418.679,1458691200,1458777599 +2016-03-22,415.841,1458604800,1458691199 +2016-03-21,413.755,1458518400,1458604799 +2016-03-20,412.535,1458432000,1458518399 +2016-03-19,410.266,1458345600,1458431999 +2016-03-18,420.621,1458259200,1458345599 +2016-03-17,419.004,1458172800,1458259199 +2016-03-16,417.258,1458086400,1458172799 +2016-03-15,417.285,1458000000,1458086399 +2016-03-14,415.375,1457913600,1457999999 +2016-03-13,414.114,1457827200,1457913599 +2016-03-12,421.743,1457740800,1457827199 +2016-03-11,420.529,1457654400,1457740799 +2016-03-10,416.186,1457568000,1457654399 +2016-03-09,415.002,1457481600,1457567999 +2016-03-08,415.282,1457395200,1457481599 +2016-03-07,411.812,1457308800,1457395199 +2016-03-06,406.239,1457222400,1457308799 +2016-03-05,411.098,1457136000,1457222399 +2016-03-04,423.415,1457049600,1457135999 +2016-03-03,424.681,1456963200,1457049599 +2016-03-02,435.520,1456876800,1456963199 +2016-03-01,438.675,1456790400,1456876799 +2016-02-29,437.506,1456704000,1456790399 +2016-02-28,434.101,1456617600,1456703999 +2016-02-27,433.192,1456531200,1456617599 +2016-02-26,427.780,1456444800,1456531199 +2016-02-25,426.337,1456358400,1456444799 +2016-02-24,423.143,1456272000,1456358399 +2016-02-23,438.803,1456185600,1456271999 +2016-02-22,438.922,1456099200,1456185599 +2016-02-21,442.605,1456012800,1456099199 +2016-02-20,431.385,1455926400,1456012799 +2016-02-19,422.739,1455840000,1455926399 +2016-02-18,421.159,1455753600,1455839999 +2016-02-17,414.328,1455667200,1455753599 +2016-02-16,404.565,1455580800,1455667199 +2016-02-15,408.806,1455494400,1455580799 +2016-02-14,399.507,1455408000,1455494399 +2016-02-13,387.738,1455321600,1455407999 +2016-02-12,382.304,1455235200,1455321599 +2016-02-11,382.390,1455148800,1455235199 +2016-02-10,380.756,1455062400,1455148799 +2016-02-09,375.347,1454976000,1455062399 +2016-02-08,378.250,1454889600,1454975999 +2016-02-07,378.697,1454803200,1454889599 +2016-02-06,386.590,1454716800,1454803199 +2016-02-05,390.344,1454630400,1454716799 +2016-02-04,380.779,1454544000,1454630399 +2016-02-03,374.699,1454457600,1454543999 +2016-02-02,374.470,1454371200,1454457599 +2016-02-01,373.420,1454284800,1454371199 +2016-01-31,379.301,1454198400,1454284799 +2016-01-30,380.196,1454112000,1454198399 +2016-01-29,382.334,1454025600,1454111999 +2016-01-28,395.237,1453939200,1454025599 +2016-01-27,394.498,1453852800,1453939199 +2016-01-26,394.746,1453766400,1453852799 +2016-01-25,402.971,1453680000,1453766399 +2016-01-24,396.488,1453593600,1453679999 +2016-01-23,388.518,1453507200,1453593599 +2016-01-22,410.336,1453420800,1453507199 +2016-01-21,421.554,1453334400,1453420799 +2016-01-20,402.708,1453248000,1453334399 +2016-01-19,387.449,1453161600,1453247999 +2016-01-18,385.202,1453075200,1453161599 +2016-01-17,389.251,1452988800,1453075199 +2016-01-16,377.444,1452902400,1452988799 +2016-01-15,430.306,1452816000,1452902399 +2016-01-14,432.848,1452729600,1452815999 +2016-01-13,435.690,1452643200,1452729599 +2016-01-12,448.428,1452556800,1452643199 +2016-01-11,449.327,1452470400,1452556799 +2016-01-10,447.960,1452384000,1452470399 +2016-01-09,453.935,1452297600,1452383999 +2016-01-08,460.491,1452211200,1452297599 +2016-01-07,443.936,1452124800,1452211199 +2016-01-06,431.960,1452038400,1452124799 +2016-01-05,433.637,1451952000,1452038399 +2016-01-04,432.264,1451865600,1451951999 +2016-01-03,433.591,1451779200,1451865599 +2016-01-02,435.198,1451692800,1451779199 +2016-01-01,433.407,1451606400,1451692799 +2015-12-31,429.771,1451520000,1451606399 +2015-12-30,433.685,1451433600,1451519999 +2015-12-29,427.311,1451347200,1451433599 +2015-12-28,426.296,1451260800,1451347199 +2015-12-27,420.641,1451174400,1451260799 +2015-12-26,456.571,1451088000,1451174399 +2015-12-25,456.645,1451001600,1451087999 +2015-12-24,450.429,1450915200,1451001599 +2015-12-23,440.551,1450828800,1450915199 +2015-12-22,441.164,1450742400,1450828799 +2015-12-21,443.707,1450656000,1450742399 +2015-12-20,462.484,1450569600,1450655999 +2015-12-19,464.599,1450483200,1450569599 +2015-12-18,460.628,1450396800,1450483199 +2015-12-17,456.397,1450310400,1450396799 +2015-12-16,465.321,1450224000,1450310399 +2015-12-15,454.398,1450137600,1450223999 +2015-12-14,440.449,1450051200,1450137599 +2015-12-13,438.339,1449964800,1450051199 +2015-12-12,460.521,1449878400,1449964799 +2015-12-11,433.586,1449792000,1449878399 +2015-12-10,418.536,1449705600,1449791999 +2015-12-09,419.342,1449619200,1449705599 +2015-12-08,404.323,1449532800,1449619199 +2015-12-07,394.376,1449446400,1449532799 +2015-12-06,395.879,1449360000,1449446399 +2015-12-05,376.484,1449273600,1449359999 +2015-12-04,362.281,1449187200,1449273599 +2015-12-03,364.731,1449100800,1449187199 +2015-12-02,362.488,1449014400,1449100799 +2015-12-01,378.126,1448928000,1449014399 +2015-11-30,376.829,1448841600,1448927999 +2015-11-29,364.660,1448755200,1448841599 +2015-11-28,358.789,1448668800,1448755199 +2015-11-27,358.137,1448582400,1448668799 +2015-11-26,347.482,1448496000,1448582399 +2015-11-25,324.590,1448409600,1448495999 +2015-11-24,323.052,1448323200,1448409599 +2015-11-23,324.827,1448236800,1448323199 +2015-11-22,326.969,1448150400,1448236799 +2015-11-21,325.091,1448064000,1448150399 +2015-11-20,326.311,1447977600,1448063999 +2015-11-19,334.962,1447891200,1447977599 +2015-11-18,335.813,1447804800,1447891199 +2015-11-17,334.551,1447718400,1447804799 +2015-11-16,325.896,1447632000,1447718399 +2015-11-15,333.784,1447545600,1447631999 +2015-11-14,337.467,1447459200,1447545599 +2015-11-13,339.533,1447372800,1447459199 +2015-11-12,328.083,1447286400,1447372799 +2015-11-11,338.702,1447200000,1447286399 +2015-11-10,380.822,1447113600,1447199999 +2015-11-09,379.323,1447027200,1447113599 +2015-11-08,388.189,1446940800,1447027199 +2015-11-07,382.528,1446854400,1446940799 +2015-11-06,391.095,1446768000,1446854399 +2015-11-05,429.562,1446681600,1446767999 +2015-11-04,449.490,1446595200,1446681599 +2015-11-03,389.545,1446508800,1446595199 +2015-11-02,345.396,1446422400,1446508799 +2015-11-01,320.819,1446336000,1446422399 +2015-10-31,330.396,1446249600,1446335999 +2015-10-30,324.012,1446163200,1446249599 +2015-10-29,311.394,1446076800,1446163199 +2015-10-28,300.060,1445990400,1446076799 +2015-10-27,290.756,1445904000,1445990399 +2015-10-26,284.484,1445817600,1445903999 +2015-10-25,287.857,1445731200,1445817599 +2015-10-24,279.101,1445644800,1445731199 +2015-10-23,276.354,1445558400,1445644799 +2015-10-22,271.391,1445472000,1445558399 +2015-10-21,270.117,1445385600,1445471999 +2015-10-20,267.136,1445299200,1445385599 +2015-10-19,263.232,1445212800,1445299199 +2015-10-18,271.154,1445126400,1445212799 +2015-10-17,268.224,1445040000,1445126399 +2015-10-16,260.228,1444953600,1445039999 +2015-10-15,253.976,1444867200,1444953599 +2015-10-14,251.892,1444780800,1444867199 +2015-10-13,247.772,1444694400,1444780799 +2015-10-12,247.252,1444608000,1444694399 +2015-10-11,246.092,1444521600,1444607999 +2015-10-10,244.625,1444435200,1444521599 +2015-10-09,243.266,1444348800,1444435199 +2015-10-08,243.610,1444262400,1444348799 +2015-10-07,246.372,1444176000,1444262399 +2015-10-06,243.659,1444089600,1444175999 +2015-10-05,239.321,1444003200,1444089599 +2015-10-04,238.849,1443916800,1444003199 +2015-10-03,238.304,1443830400,1443916799 +2015-10-02,238.045,1443744000,1443830399 +2015-10-01,237.253,1443657600,1443743999 +2015-09-30,237.211,1443571200,1443657599 +2015-09-29,239.472,1443484800,1443571199 +2015-09-28,236.048,1443398400,1443484799 +2015-09-27,234.433,1443312000,1443398399 +2015-09-26,235.274,1443225600,1443311999 +2015-09-25,235.978,1443139200,1443225599 +2015-09-24,232.966,1443052800,1443139199 +2015-09-23,231.227,1442966400,1443052799 +2015-09-22,229.736,1442880000,1442966399 +2015-09-21,231.215,1442793600,1442879999 +2015-09-20,231.929,1442707200,1442793599 +2015-09-19,233.090,1442620800,1442707199 +2015-09-18,233.937,1442534400,1442620799 +2015-09-17,229.688,1442448000,1442534399 +2015-09-16,230.760,1442361600,1442447999 +2015-09-15,244.913,1442275200,1442361599 +2015-09-14,231.476,1442188800,1442275199 +2015-09-13,235.582,1442102400,1442188799 +2015-09-12,240.116,1442016000,1442102399 +2015-09-11,239.823,1441929600,1442015999 +2015-09-10,239.731,1441843200,1441929599 +2015-09-09,244.012,1441756800,1441843199 +2015-09-08,242.814,1441670400,1441756799 +2015-09-07,240.973,1441584000,1441670399 +2015-09-06,238.966,1441497600,1441583999 +2015-09-05,233.221,1441411200,1441497599 +2015-09-04,229.042,1441324800,1441411199 +2015-09-03,229.445,1441238400,1441324799 +2015-09-02,229.349,1441152000,1441238399 +2015-09-01,230.636,1441065600,1441151999 +2015-08-31,230.359,1440979200,1441065599 +2015-08-30,230.924,1440892800,1440979199 +2015-08-29,232.309,1440806400,1440892799 +2015-08-28,229.994,1440720000,1440806399 +2015-08-27,227.237,1440633600,1440719999 +2015-08-26,226.396,1440547200,1440633599 +2015-08-25,218.408,1440460800,1440547199 +2015-08-24,228.169,1440374400,1440460799 +2015-08-23,231.548,1440288000,1440374399 +2015-08-22,233.763,1440201600,1440287999 +2015-08-21,235.891,1440115200,1440201599 +2015-08-20,232.025,1440028800,1440115199 +2015-08-19,224.244,1439942400,1440028799 +2015-08-18,257.985,1439856000,1439942399 +2015-08-17,259.506,1439769600,1439855999 +2015-08-16,261.996,1439683200,1439769599 +2015-08-15,266.174,1439596800,1439683199 +2015-08-14,265.773,1439510400,1439596799 +2015-08-13,266.376,1439424000,1439510399 +2015-08-12,270.530,1439337600,1439423999 +2015-08-11,267.379,1439251200,1439337599 +2015-08-10,266.058,1439164800,1439251199 +2015-08-09,264.000,1439078400,1439164799 +2015-08-08,279.757,1438992000,1439078399 +2015-08-07,279.485,1438905600,1438991999 +2015-08-06,281.894,1438819200,1438905599 +2015-08-05,285.360,1438732800,1438819199 +2015-08-04,283.471,1438646400,1438732799 +2015-08-03,284.043,1438560000,1438646399 +2015-08-02,282.317,1438473600,1438559999 +2015-08-01,284.791,1438387200,1438473599 +2015-07-31,288.341,1438300800,1438387199 +2015-07-30,289.858,1438214400,1438300799 +2015-07-29,294.482,1438128000,1438214399 +2015-07-28,295.137,1438041600,1438127999 +2015-07-27,295.230,1437955200,1438041599 +2015-07-26,290.875,1437868800,1437955199 +2015-07-25,289.506,1437782400,1437868799 +2015-07-24,282.651,1437696000,1437782399 +2015-07-23,277.667,1437609600,1437695999 +2015-07-22,276.750,1437523200,1437609599 +2015-07-21,279.764,1437436800,1437523199 +2015-07-20,276.007,1437350400,1437436799 +2015-07-19,275.286,1437264000,1437350399 +2015-07-18,281.000,1437177600,1437263999 +2015-07-17,279.185,1437091200,1437177599 +2015-07-16,288.506,1437004800,1437091199 +2015-07-15,290.356,1436918400,1437004799 +2015-07-14,294.101,1436832000,1436918399 +2015-07-13,310.908,1436745600,1436831999 +2015-07-12,303.755,1436659200,1436745599 +2015-07-11,291.700,1436572800,1436659199 +2015-07-10,281.910,1436486400,1436572799 +2015-07-09,271.560,1436400000,1436486399 +2015-07-08,269.589,1436313600,1436399999 +2015-07-07,270.186,1436227200,1436313599 +2015-07-06,274.668,1436140800,1436227199 +2015-07-05,267.696,1436054400,1436140799 +2015-07-04,258.897,1435968000,1436054399 +2015-07-03,256.245,1435881600,1435967999 +2015-07-02,260.126,1435795200,1435881599 +2015-07-01,264.122,1435708800,1435795199 +2015-06-30,262.466,1435622400,1435708799 +2015-06-29,253.092,1435536000,1435622399 +2015-06-28,251.081,1435449600,1435535999 +2015-06-27,247.467,1435363200,1435449599 +2015-06-26,243.274,1435276800,1435363199 +2015-06-25,241.924,1435190400,1435276799 +2015-06-24,244.319,1435104000,1435190399 +2015-06-23,247.147,1435017600,1435103999 +2015-06-22,245.931,1434931200,1435017599 +2015-06-21,245.218,1434844800,1434931199 +2015-06-20,245.217,1434758400,1434844799 +2015-06-19,249.992,1434672000,1434758399 +2015-06-18,250.696,1434585600,1434671999 +2015-06-17,253.874,1434499200,1434585599 +2015-06-16,244.283,1434412800,1434499199 +2015-06-15,235.690,1434326400,1434412799 +2015-06-14,233.630,1434240000,1434326399 +2015-06-13,231.317,1434153600,1434239999 +2015-06-12,230.381,1434067200,1434153599 +2015-06-11,229.545,1433980800,1434067199 +2015-06-10,229.415,1433894400,1433980799 +2015-06-09,229.722,1433808000,1433894399 +2015-06-08,226.173,1433721600,1433807999 +2015-06-07,225.907,1433635200,1433721599 +2015-06-06,225.336,1433548800,1433635199 +2015-06-05,225.146,1433462400,1433548799 +2015-06-04,226.228,1433376000,1433462399 +2015-06-03,226.604,1433289600,1433375999 +2015-06-02,224.655,1433203200,1433289599 +2015-06-01,230.952,1433116800,1433203199 +2015-05-31,233.345,1433030400,1433116799 +2015-05-30,237.096,1432944000,1433030399 +2015-05-29,237.465,1432857600,1432943999 +2015-05-28,237.554,1432771200,1432857599 +2015-05-27,237.876,1432684800,1432771199 +2015-05-26,237.676,1432598400,1432684799 +2015-05-25,240.987,1432512000,1432598399 +2015-05-24,240.425,1432425600,1432511999 +2015-05-23,240.687,1432339200,1432425599 +2015-05-22,238.157,1432252800,1432339199 +2015-05-21,235.130,1432166400,1432252799 +2015-05-20,233.315,1432080000,1432166399 +2015-05-19,233.640,1431993600,1432079999 +2015-05-18,237.006,1431907200,1431993599 +2015-05-17,237.089,1431820800,1431907199 +2015-05-16,237.651,1431734400,1431820799 +2015-05-15,237.841,1431648000,1431734399 +2015-05-14,237.088,1431561600,1431647999 +2015-05-13,242.408,1431475200,1431561599 +2015-05-12,242.520,1431388800,1431475199 +2015-05-11,242.283,1431302400,1431388799 +2015-05-10,242.950,1431216000,1431302399 +2015-05-09,245.834,1431129600,1431215999 +2015-05-08,241.805,1431043200,1431129599 +2015-05-07,234.444,1430956800,1431043199 +2015-05-06,236.352,1430870400,1430956799 +2015-05-05,239.111,1430784000,1430870399 +2015-05-04,241.498,1430697600,1430783999 +2015-05-03,239.085,1430611200,1430697599 +2015-05-02,233.903,1430524800,1430611199 +2015-05-01,237.556,1430438400,1430524799 +2015-04-30,232.686,1430352000,1430438399 +2015-04-29,226.448,1430265600,1430351999 +2015-04-28,229.391,1430179200,1430265599 +2015-04-27,226.368,1430092800,1430179199 +2015-04-26,226.667,1430006400,1430092799 +2015-04-25,231.915,1429920000,1430006399 +2015-04-24,236.462,1429833600,1429919999 +2015-04-23,235.326,1429747200,1429833599 +2015-04-22,236.589,1429660800,1429747199 +2015-04-21,229.874,1429574400,1429660799 +2015-04-20,224.476,1429488000,1429574399 +2015-04-19,224.855,1429401600,1429487999 +2015-04-18,223.599,1429315200,1429401599 +2015-04-17,228.740,1429228800,1429315199 +2015-04-16,226.753,1429142400,1429228799 +2015-04-15,221.408,1429056000,1429142399 +2015-04-14,224.782,1428969600,1429055999 +2015-04-13,236.544,1428883200,1428969599 +2015-04-12,237.140,1428796800,1428883199 +2015-04-11,237.805,1428710400,1428796799 +2015-04-10,243.685,1428624000,1428710399 +2015-04-09,245.570,1428537600,1428623999 +2015-04-08,253.514,1428451200,1428537599 +2015-04-07,255.649,1428364800,1428451199 +2015-04-06,261.198,1428278400,1428364799 +2015-04-05,257.186,1428192000,1428278399 +2015-04-04,254.790,1428105600,1428191999 +2015-04-03,254.524,1428019200,1428105599 +2015-04-02,250.867,1427932800,1428019199 +2015-04-01,245.883,1427846400,1427932799 +2015-03-31,248.128,1427760000,1427846399 +2015-03-30,245.978,1427673600,1427759999 +2015-03-29,252.969,1427587200,1427673599 +2015-03-28,250.617,1427500800,1427587199 +2015-03-27,252.672,1427414400,1427500799 +2015-03-26,250.276,1427328000,1427414399 +2015-03-25,247.393,1427241600,1427327999 +2015-03-24,266.872,1427155200,1427241599 +2015-03-23,272.629,1427068800,1427155199 +2015-03-22,264.886,1426982400,1427068799 +2015-03-21,261.973,1426896000,1426982399 +2015-03-20,262.888,1426809600,1426895999 +2015-03-19,260.272,1426723200,1426809599 +2015-03-18,285.505,1426636800,1426723199 +2015-03-17,291.479,1426550400,1426636799 +2015-03-16,290.253,1426464000,1426550399 +2015-03-15,284.207,1426377600,1426463999 +2015-03-14,285.840,1426291200,1426377599 +2015-03-13,294.426,1426204800,1426291199 +2015-03-12,296.734,1426118400,1426204799 +2015-03-11,294.576,1426032000,1426118399 +2015-03-10,294.826,1425945600,1426031999 +2015-03-09,283.528,1425859200,1425945599 +2015-03-08,277.060,1425772800,1425859199 +2015-03-07,275.289,1425686400,1425772799 +2015-03-06,276.893,1425600000,1425686399 +2015-03-05,277.380,1425513600,1425599999 +2015-03-04,283.108,1425427200,1425513599 +2015-03-03,280.733,1425340800,1425427199 +2015-03-02,268.252,1425254400,1425340799 +2015-03-01,257.962,1425168000,1425254399 +2015-02-28,254.106,1425081600,1425167999 +2015-02-27,246.540,1424995200,1425081599 +2015-02-26,237.590,1424908800,1424995199 +2015-02-25,239.038,1424822400,1424908799 +2015-02-24,239.397,1424736000,1424822399 +2015-02-23,238.043,1424649600,1424735999 +2015-02-22,245.463,1424563200,1424649599 +2015-02-21,249.550,1424476800,1424563199 +2015-02-20,243.692,1424390400,1424476799 +2015-02-19,239.499,1424304000,1424390399 +2015-02-18,243.931,1424217600,1424303999 +2015-02-17,239.809,1424131200,1424217599 +2015-02-16,237.173,1424044800,1424131199 +2015-02-15,261.466,1423958400,1424044799 +2015-02-14,247.618,1423872000,1423958399 +2015-02-13,231.012,1423785600,1423871999 +2015-02-12,220.692,1423699200,1423785599 +2015-02-11,221.569,1423612800,1423699199 +2015-02-10,220.959,1423526400,1423612799 +2015-02-09,223.695,1423440000,1423526399 +2015-02-08,228.596,1423353600,1423439999 +2015-02-07,226.283,1423267200,1423353599 +2015-02-06,223.811,1423180800,1423267199 +2015-02-05,233.129,1423094400,1423180799 +2015-02-04,228.663,1423008000,1423094399 +2015-02-03,242.093,1422921600,1423007999 +2015-02-02,234.574,1422835200,1422921599 +2015-02-01,224.519,1422748800,1422835199 +2015-01-31,229.965,1422662400,1422748799 +2015-01-30,238.182,1422576000,1422662399 +2015-01-29,236.311,1422489600,1422575999 +2015-01-28,265.005,1422403200,1422489599 +2015-01-27,274.477,1422316800,1422403199 +2015-01-26,281.551,1422230400,1422316799 +2015-01-25,251.461,1422144000,1422230399 +2015-01-24,240.545,1422057600,1422143999 +2015-01-23,234.126,1421971200,1422057599 +2015-01-22,231.958,1421884800,1421971199 +2015-01-21,219.552,1421798400,1421884799 +2015-01-20,215.051,1421712000,1421798399 +2015-01-19,213.534,1421625600,1421711999 +2015-01-18,208.978,1421539200,1421625599 +2015-01-17,209.914,1421452800,1421539199 +2015-01-16,215.718,1421366400,1421452799 +2015-01-15,203.585,1421280000,1421366399 +2015-01-14,225.861,1421193600,1421279999 +2015-01-13,268.037,1421107200,1421193599 +2015-01-12,268.932,1421020800,1421107199 +2015-01-11,277.217,1420934400,1421020799 +2015-01-10,287.715,1420848000,1420934399 +2015-01-09,287.232,1420761600,1420847999 +2015-01-08,294.337,1420675200,1420761599 +2015-01-07,292.472,1420588800,1420675199 +2015-01-06,281.014,1420502400,1420588799 +2015-01-05,271.268,1420416000,1420502399 +2015-01-04,284.156,1420329600,1420415999 +2015-01-03,315.091,1420243200,1420329599 +2015-01-02,315.044,1420156800,1420243199 +2015-01-01,320.314,1420070400,1420156799 +2014-12-31,315.360,1419984000,1420070399 +2014-12-30,313.740,1419897600,1419983999 +2014-12-29,318.753,1419811200,1419897599 +2014-12-28,317.946,1419724800,1419811199 +2014-12-27,328.418,1419638400,1419724799 +2014-12-26,325.216,1419552000,1419638399 +2014-12-25,322.602,1419465600,1419551999 +2014-12-24,334.657,1419379200,1419465599 +2014-12-23,334.087,1419292800,1419379199 +2014-12-22,327.480,1419206400,1419292799 +2014-12-21,329.956,1419120000,1419206399 +2014-12-20,324.084,1419033600,1419119999 +2014-12-19,314.965,1418947200,1419033599 +2014-12-18,321.743,1418860800,1418947199 +2014-12-17,330.508,1418774400,1418860799 +2014-12-16,345.602,1418688000,1418774399 +2014-12-15,351.724,1418601600,1418687999 +2014-12-14,350.346,1418515200,1418601599 +2014-12-13,352.381,1418428800,1418515199 +2014-12-12,351.908,1418342400,1418428799 +2014-12-11,353.861,1418256000,1418342399 +2014-12-10,352.302,1418169600,1418255999 +2014-12-09,362.488,1418083200,1418169599 +2014-12-08,375.562,1417996800,1418083199 +2014-12-07,375.539,1417910400,1417996799 +2014-12-06,377.651,1417824000,1417910399 +2014-12-05,374.398,1417737600,1417823999 +2014-12-04,376.833,1417651200,1417737599 +2014-12-03,382.171,1417564800,1417651199 +2014-12-02,381.642,1417478400,1417564799 +2014-12-01,380.855,1417392000,1417478399 +2014-11-30,379.009,1417305600,1417391999 +2014-11-29,382.024,1417219200,1417305599 +2014-11-28,376.254,1417132800,1417219199 +2014-11-27,371.181,1417046400,1417132799 +2014-11-26,376.523,1416960000,1417046399 +2014-11-25,385.801,1416873600,1416959999 +2014-11-24,377.391,1416787200,1416873599 +2014-11-23,361.883,1416700800,1416787199 +2014-11-22,357.845,1416614400,1416700799 +2014-11-21,357.860,1416528000,1416614399 +2014-11-20,381.290,1416441600,1416527999 +2014-11-19,380.840,1416355200,1416441599 +2014-11-18,389.905,1416268800,1416355199 +2014-11-17,399.041,1416182400,1416268799 +2014-11-16,383.466,1416096000,1416182399 +2014-11-15,401.673,1416009600,1416095999 +2014-11-14,420.735,1415923200,1416009599 +2014-11-13,440.327,1415836800,1415923199 +2014-11-12,398.707,1415750400,1415836799 +2014-11-11,369.117,1415664000,1415750399 +2014-11-10,369.040,1415577600,1415663999 +2014-11-09,354.557,1415491200,1415577599 +2014-11-08,344.724,1415404800,1415491199 +2014-11-07,351.011,1415318400,1415404799 +2014-11-06,346.226,1415232000,1415318399 +2014-11-05,336.931,1415145600,1415231999 +2014-11-04,329.661,1415059200,1415145599 +2014-11-03,329.947,1414972800,1415059199 +2014-11-02,327.400,1414886400,1414972799 +2014-11-01,339.425,1414800000,1414886399 +2014-10-31,346.675,1414713600,1414799999 +2014-10-30,343.252,1414627200,1414713599 +2014-10-29,357.726,1414540800,1414627199 +2014-10-28,356.487,1414454400,1414540799 +2014-10-27,356.668,1414368000,1414454399 +2014-10-26,353.246,1414281600,1414367999 +2014-10-25,359.103,1414195200,1414281599 +2014-10-24,361.381,1414108800,1414195199 +2014-10-23,384.103,1414022400,1414108799 +2014-10-22,387.526,1413936000,1414022399 +2014-10-21,387.746,1413849600,1413935999 +2014-10-20,389.815,1413763200,1413849599 +2014-10-19,392.691,1413676800,1413763199 +2014-10-18,389.458,1413590400,1413676799 +2014-10-17,384.017,1413504000,1413590399 +2014-10-16,396.790,1413417600,1413503999 +2014-10-15,401.549,1413331200,1413417599 +2014-10-14,401.056,1413244800,1413331199 +2014-10-13,387.888,1413158400,1413244799 +2014-10-12,370.866,1413072000,1413158399 +2014-10-11,364.377,1412985600,1413071999 +2014-10-10,370.047,1412899200,1412985599 +2014-10-09,367.833,1412812800,1412899199 +2014-10-08,345.276,1412726400,1412812799 +2014-10-07,334.663,1412640000,1412726399 +2014-10-06,332.822,1412553600,1412639999 +2014-10-05,335.334,1412467200,1412553599 +2014-10-04,362.000,1412380800,1412467199 +2014-10-03,376.384,1412294400,1412380799 +2014-10-02,384.743,1412208000,1412294399 +2014-10-01,389.162,1412121600,1412207999 +2014-09-30,383.222,1412035200,1412121599 +2014-09-29,381.196,1411948800,1412035199 +2014-09-28,400.269,1411862400,1411948799 +2014-09-27,405.524,1411776000,1411862399 +2014-09-26,413.256,1411689600,1411775999 +2014-09-25,423.363,1411603200,1411689599 +2014-09-24,435.952,1411516800,1411603199 +2014-09-23,421.855,1411430400,1411516799 +2014-09-22,402.869,1411344000,1411430399 +2014-09-21,410.665,1411257600,1411343999 +2014-09-20,409.046,1411171200,1411257599 +2014-09-19,426.138,1411084800,1411171199 +2014-09-18,457.334,1410998400,1411084799 +2014-09-17,467.116,1410912000,1410998399 +2014-09-16,475.507,1410825600,1410911999 +2014-09-15,478.256,1410739200,1410825599 +2014-09-14,479.428,1410652800,1410739199 +2014-09-13,479.935,1410566400,1410652799 +2014-09-12,479.749,1410480000,1410566399 +2014-09-11,480.855,1410393600,1410479999 +2014-09-10,481.364,1410307200,1410393599 +2014-09-09,475.989,1410220800,1410307199 +2014-09-08,486.056,1410134400,1410220799 +2014-09-07,486.448,1410048000,1410134399 +2014-09-06,485.969,1409961600,1410047999 +2014-09-05,490.152,1409875200,1409961599 +2014-09-04,485.757,1409788800,1409875199 +2014-09-03,479.569,1409702400,1409788799 +2014-09-02,478.934,1409616000,1409702399 +2014-09-01,481.535,1409529600,1409615999 +2014-08-31,504.564,1409443200,1409529599 +2014-08-30,508.913,1409356800,1409443199 +2014-08-29,509.755,1409270400,1409356799 +2014-08-28,513.655,1409184000,1409270399 +2014-08-27,516.140,1409097600,1409183999 +2014-08-26,507.592,1409011200,1409097599 +2014-08-25,508.286,1408924800,1409011199 +2014-08-24,505.482,1408838400,1408924799 +2014-08-23,514.171,1408752000,1408838399 +2014-08-22,519.358,1408665600,1408751999 +2014-08-21,521.940,1408579200,1408665599 +2014-08-20,501.765,1408492800,1408579199 +2014-08-19,473.585,1408406400,1408492799 +2014-08-18,495.583,1408320000,1408406399 +2014-08-17,519.949,1408233600,1408319999 +2014-08-16,509.243,1408147200,1408233599 +2014-08-15,512.077,1408060800,1408147199 +2014-08-14,546.658,1407974400,1408060799 +2014-08-13,571.338,1407888000,1407974399 +2014-08-12,576.658,1407801600,1407887999 +2014-08-11,591.284,1407715200,1407801599 +2014-08-10,591.916,1407628800,1407715199 +2014-08-09,592.577,1407542400,1407628799 +2014-08-08,593.493,1407456000,1407542399 +2014-08-07,587.879,1407369600,1407455999 +2014-08-06,586.461,1407283200,1407369599 +2014-08-05,589.324,1407196800,1407283199 +2014-08-04,589.306,1407110400,1407196799 +2014-08-03,589.333,1407024000,1407110399 +2014-08-02,594.916,1406937600,1407023999 +2014-08-01,592.079,1406851200,1406937599 +2014-07-31,576.764,1406764800,1406851199 +2014-07-30,584.924,1406678400,1406764799 +2014-07-29,587.038,1406592000,1406678399 +2014-07-28,594.213,1406505600,1406591999 +2014-07-27,597.378,1406419200,1406505599 +2014-07-26,601.589,1406332800,1406419199 +2014-07-25,604.399,1406246400,1406332799 +2014-07-24,619.922,1406160000,1406246399 +2014-07-23,622.991,1406073600,1406159999 +2014-07-22,623.255,1405987200,1406073599 +2014-07-21,623.995,1405900800,1405987199 +2014-07-20,628.537,1405814400,1405900799 +2014-07-19,628.973,1405728000,1405814399 +2014-07-18,626.151,1405641600,1405727999 +2014-07-17,621.545,1405555200,1405641599 +2014-07-16,622.339,1405468800,1405555199 +2014-07-15,622.228,1405382400,1405468799 +2014-07-14,626.920,1405296000,1405382399 +2014-07-13,634.220,1405209600,1405295999 +2014-07-12,634.331,1405123200,1405209599 +2014-07-11,624.424,1405036800,1405123199 +2014-07-10,625.313,1404950400,1405036799 +2014-07-09,626.110,1404864000,1404950399 +2014-07-08,624.633,1404777600,1404863999 +2014-07-07,636.310,1404691200,1404777599 +2014-07-06,635.213,1404604800,1404691199 +2014-07-05,631.587,1404518400,1404604799 +2014-07-04,646.540,1404432000,1404518399 +2014-07-03,650.769,1404345600,1404431999 +2014-07-02,648.858,1404259200,1404345599 +2014-07-01,649.625,1404172800,1404259199 +2014-06-30,623.888,1404086400,1404172799 +2014-06-29,600.204,1404000000,1404086399 +2014-06-28,601.775,1403913600,1403999999 +2014-06-27,590.711,1403827200,1403913599 +2014-06-26,573.883,1403740800,1403827199 +2014-06-25,582.704,1403654400,1403740799 +2014-06-24,595.471,1403568000,1403654399 +2014-06-23,602.687,1403481600,1403567999 +2014-06-22,600.951,1403395200,1403481599 +2014-06-21,596.570,1403308800,1403395199 +2014-06-20,598.578,1403222400,1403308799 +2014-06-19,610.156,1403136000,1403222399 +2014-06-18,612.824,1403049600,1403135999 +2014-06-17,601.238,1402963200,1403049599 +2014-06-16,600.685,1402876800,1402963199 +2014-06-15,584.433,1402790400,1402876799 +2014-06-14,601.008,1402704000,1402790399 +2014-06-13,600.417,1402617600,1402703999 +2014-06-12,635.769,1402531200,1402617599 +2014-06-11,655.114,1402444800,1402531199 +2014-06-10,654.829,1402358400,1402444799 +2014-06-09,656.672,1402272000,1402358399 +2014-06-08,656.939,1402185600,1402271999 +2014-06-07,655.233,1402099200,1402185599 +2014-06-06,660.325,1402012800,1402099199 +2014-06-05,652.299,1401926400,1402012799 +2014-06-04,667.669,1401840000,1401926399 +2014-06-03,667.331,1401753600,1401839999 +2014-06-02,647.572,1401667200,1401753599 +2014-06-01,647.603,1401580800,1401667199 +2014-05-31,620.201,1401494400,1401580799 +2014-05-30,593.318,1401408000,1401494399 +2014-05-29,576.713,1401321600,1401407999 +2014-05-28,575.270,1401235200,1401321599 +2014-05-27,586.053,1401148800,1401235199 +2014-05-26,579.891,1401062400,1401148799 +2014-05-25,550.853,1400976000,1401062399 +2014-05-24,523.111,1400889600,1400975999 +2014-05-23,533.836,1400803200,1400889599 +2014-05-22,508.703,1400716800,1400803199 +2014-05-21,490.085,1400630400,1400716799 +2014-05-20,468.875,1400544000,1400630399 +2014-05-19,446.816,1400457600,1400543999 +2014-05-18,449.234,1400371200,1400457599 +2014-05-17,450.049,1400284800,1400371199 +2014-05-16,449.024,1400198400,1400284799 +2014-05-15,446.968,1400112000,1400198399 +2014-05-14,443.626,1400025600,1400111999 +2014-05-13,441.754,1399939200,1400025599 +2014-05-12,440.282,1399852800,1399939199 +2014-05-11,454.630,1399766400,1399852799 +2014-05-10,453.114,1399680000,1399766399 +2014-05-09,446.435,1399593600,1399679999 +2014-05-08,443.539,1399507200,1399593599 +2014-05-07,437.735,1399420800,1399507199 +2014-05-06,440.701,1399334400,1399420799 +2014-05-05,437.878,1399248000,1399334399 +2014-05-04,439.143,1399161600,1399247999 +2014-05-03,449.403,1399075200,1399161599 +2014-05-02,457.647,1398988800,1399075199 +2014-05-01,454.124,1398902400,1398988799 +2014-04-30,448.995,1398816000,1398902399 +2014-04-29,445.810,1398729600,1398815999 +2014-04-28,439.125,1398643200,1398729599 +2014-04-27,458.286,1398556800,1398643199 +2014-04-26,463.124,1398470400,1398556799 +2014-04-25,500.193,1398384000,1398470399 +2014-04-24,495.645,1398297600,1398383999 +2014-04-23,490.804,1398211200,1398297599 +2014-04-22,499.339,1398124800,1398211199 +2014-04-21,504.154,1398038400,1398124799 +2014-04-20,506.311,1397952000,1398038399 +2014-04-19,491.569,1397865600,1397951999 +2014-04-18,497.200,1397779200,1397865599 +2014-04-17,531.292,1397692800,1397779199 +2014-04-16,532.282,1397606400,1397692799 +2014-04-15,488.685,1397520000,1397606399 +2014-04-14,442.290,1397433600,1397519999 +2014-04-13,424.430,1397347200,1397433599 +2014-04-12,430.248,1397260800,1397347199 +2014-04-11,396.739,1397174400,1397260799 +2014-04-10,442.811,1397088000,1397174399 +2014-04-09,454.453,1397001600,1397087999 +2014-04-08,452.519,1396915200,1397001599 +2014-04-07,462.019,1396828800,1396915199 +2014-04-06,464.858,1396742400,1396828799 +2014-04-05,455.123,1396656000,1396742399 +2014-04-04,450.158,1396569600,1396655999 +2014-04-03,443.005,1396483200,1396569599 +2014-04-02,487.091,1396396800,1396483199 +2014-04-01,476.172,1396310400,1396396799 +2014-03-31,472.661,1396224000,1396310399 +2014-03-30,492.372,1396137600,1396223999 +2014-03-29,503.286,1396051200,1396137599 +2014-03-28,501.583,1395964800,1396051199 +2014-03-27,580.409,1395878400,1395964799 +2014-03-26,586.755,1395792000,1395878399 +2014-03-25,585.232,1395705600,1395791999 +2014-03-24,574.535,1395619200,1395705599 +2014-03-23,568.001,1395532800,1395619199 +2014-03-22,571.864,1395446400,1395532799 +2014-03-21,596.443,1395360000,1395446399 +2014-03-20,609.745,1395273600,1395359999 +2014-03-19,617.948,1395187200,1395273599 +2014-03-18,622.115,1395100800,1395187199 +2014-03-17,631.800,1395014400,1395100799 +2014-03-16,637.010,1394928000,1395014399 +2014-03-15,634.255,1394841600,1394927999 +2014-03-14,638.835,1394755200,1394841599 +2014-03-13,638.910,1394668800,1394755199 +2014-03-12,639.970,1394582400,1394668799 +2014-03-11,633.185,1394496000,1394582399 +2014-03-10,640.545,1394409600,1394495999 +2014-03-09,630.130,1394323200,1394409599 +2014-03-08,632.400,1394236800,1394323199 +2014-03-07,664.825,1394150400,1394236799 +2014-03-06,667.145,1394064000,1394150399 +2014-03-05,670.260,1393977600,1394063999 +2014-03-04,682.230,1393891200,1393977599 +2014-03-03,632.735,1393804800,1393891199 +2014-03-02,568.855,1393718400,1393804799 +2014-03-01,561.650,1393632000,1393718399 +2014-02-28,581.920,1393545600,1393631999 +2014-02-27,587.850,1393459200,1393545599 +2014-02-26,570.420,1393372800,1393459199 +2014-02-25,540.810,1393286400,1393372799 +2014-02-24,606.825,1393200000,1393286399 +2014-02-23,623.190,1393113600,1393199999 +2014-02-22,594.360,1393027200,1393113599 +2014-02-21,569.920,1392940800,1393027199 +2014-02-20,625.410,1392854400,1392940799 +2014-02-19,628.870,1392768000,1392854399 +2014-02-18,636.460,1392681600,1392767999 +2014-02-17,635.590,1392595200,1392681599 +2014-02-16,658.200,1392508800,1392595199 +2014-02-15,661.370,1392422400,1392508799 +2014-02-14,646.445,1392336000,1392422399 +2014-02-13,654.535,1392249600,1392335999 +2014-02-12,672.640,1392163200,1392249599 +2014-02-11,697.980,1392076800,1392163199 +2014-02-10,692.515,1391990400,1392076799 +2014-02-09,691.865,1391904000,1391990399 +2014-02-08,710.695,1391817600,1391903999 +2014-02-07,783.200,1391731200,1391817599 +2014-02-06,817.700,1391644800,1391731199 +2014-02-05,833.640,1391558400,1391644799 +2014-02-04,831.970,1391472000,1391558399 +2014-02-03,825.280,1391385600,1391471999 +2014-02-02,838.810,1391299200,1391385599 +2014-02-01,841.065,1391212800,1391299199 +2014-01-31,825.150,1391126400,1391212799 +2014-01-30,828.260,1391040000,1391126399 +2014-01-29,823.415,1390953600,1391039999 +2014-01-28,803.260,1390867200,1390953599 +2014-01-27,888.800,1390780800,1390867199 +2014-01-26,875.350,1390694400,1390780799 +2014-01-25,828.845,1390608000,1390694399 +2014-01-24,822.430,1390521600,1390607999 +2014-01-23,848.515,1390435200,1390521599 +2014-01-22,868.680,1390348800,1390435199 +2014-01-21,875.425,1390262400,1390348799 +2014-01-20,878.890,1390176000,1390262399 +2014-01-19,855.310,1390089600,1390175999 +2014-01-18,828.780,1390003200,1390089599 +2014-01-17,838.700,1389916800,1390003199 +2014-01-16,863.225,1389830400,1389916799 +2014-01-15,852.965,1389744000,1389830399 +2014-01-14,849.430,1389657600,1389743999 +2014-01-13,860.740,1389571200,1389657599 +2014-01-12,924.060,1389484800,1389571199 +2014-01-11,894.400,1389398400,1389484799 +2014-01-10,858.940,1389312000,1389398399 +2014-01-09,852.915,1389225600,1389311999 +2014-01-08,833.335,1389139200,1389225599 +2014-01-07,956.115,1389052800,1389139199 +2014-01-06,976.585,1388966400,1389052799 +2014-01-05,905.475,1388880000,1388966399 +2014-01-04,841.390,1388793600,1388879999 +2014-01-03,818.500,1388707200,1388793599 +2014-01-02,796.875,1388620800,1388707199 +2014-01-01,765.160,1388534400,1388620799 +2013-12-31,760.450,1388448000,1388534399 +2013-12-30,753.975,1388361600,1388447999 +2013-12-29,738.330,1388275200,1388361599 +2013-12-28,742.520,1388188800,1388275199 +2013-12-27,770.395,1388102400,1388188799 +2013-12-26,730.845,1388016000,1388102399 +2013-12-25,674.505,1387929600,1388015999 +2013-12-24,678.375,1387843200,1387929599 +2013-12-23,646.985,1387756800,1387843199 +2013-12-22,634.260,1387670400,1387756799 +2013-12-21,637.085,1387584000,1387670399 +2013-12-20,711.690,1387497600,1387583999 +2013-12-19,613.145,1387411200,1387497599 +2013-12-18,678.760,1387324800,1387411199 +2013-12-17,730.600,1387238400,1387324799 +2013-12-16,881.290,1387152000,1387238399 +2013-12-15,880.725,1387065600,1387151999 +2013-12-14,902.250,1386979200,1387065599 +2013-12-13,908.385,1386892800,1386979199 +2013-12-12,892.360,1386806400,1386892799 +2013-12-11,995.325,1386720000,1386806399 +2013-12-10,944.775,1386633600,1386719999 +2013-12-09,857.865,1386547200,1386633599 +2013-12-08,749.910,1386460800,1386547199 +2013-12-07,844.980,1386374400,1386460799 +2013-12-06,1042.380,1386288000,1386374399 +2013-12-05,1153.545,1386201600,1386287999 +2013-12-04,1116.850,1386115200,1386201599 +2013-12-03,1071.200,1386028800,1386115199 +2013-12-02,1003.420,1385942400,1386028799 +2013-12-01,1131.000,1385856000,1385942399 +2013-11-30,1142.755,1385769600,1385855999 +2013-11-29,1094.490,1385683200,1385769599 +2013-11-28,1040.470,1385596800,1385683199 +2013-11-27,962.905,1385510400,1385596799 +2013-11-26,867.135,1385424000,1385510399 +2013-11-25,791.850,1385337600,1385423999 +2013-11-24,801.495,1385251200,1385337599 +2013-11-23,808.335,1385164800,1385251199 +2013-11-22,752.460,1385078400,1385164799 +2013-11-21,663.860,1384992000,1385078399 +2013-11-20,588.815,1384905600,1384991999 +2013-11-19,759.435,1384819200,1384905599 +2013-11-18,600.180,1384732800,1384819199 +2013-11-17,470.770,1384646400,1384732799 +2013-11-16,433.770,1384560000,1384646399 +2013-11-15,428.650,1384473600,1384559999 +2013-11-14,416.155,1384387200,1384473599 +2013-11-13,387.510,1384300800,1384387199 +2013-11-12,352.935,1384214400,1384300799 +2013-11-11,338.340,1384128000,1384214399 +2013-11-10,349.760,1384041600,1384127999 +2013-11-09,354.700,1383955200,1384041599 +2013-11-08,318.255,1383868800,1383955199 +2013-11-07,282.925,1383782400,1383868799 +2013-11-06,253.890,1383696000,1383782399 +2013-11-05,239.935,1383609600,1383695999 +2013-11-04,222.835,1383523200,1383609599 +2013-11-03,210.520,1383436800,1383523199 +2013-11-02,206.785,1383350400,1383436799 +2013-11-01,205.275,1383264000,1383350399 +2013-10-31,202.505,1383177600,1383263999 +2013-10-30,206.775,1383091200,1383177599 +2013-10-29,201.670,1383004800,1383091199 +2013-10-28,197.415,1382918400,1383004799 +2013-10-27,186.520,1382832000,1382918399 +2013-10-26,187.930,1382745600,1382831999 +2013-10-25,198.280,1382659200,1382745599 +2013-10-24,215.860,1382572800,1382659199 +2013-10-23,203.490,1382486400,1382572799 +2013-10-22,189.460,1382400000,1382486399 +2013-10-21,179.810,1382313600,1382399999 +2013-10-20,173.285,1382227200,1382313599 +2013-10-19,166.695,1382140800,1382227199 +2013-10-18,151.165,1382054400,1382140799 +2013-10-17,144.915,1381968000,1382054399 +2013-10-16,148.940,1381881600,1381967999 +2013-10-15,143.080,1381795200,1381881599 +2013-10-14,141.695,1381708800,1381795199 +2013-10-13,136.925,1381622400,1381708799 +2013-10-12,133.280,1381536000,1381622399 +2013-10-11,131.280,1381449600,1381535999 +2013-10-10,131.085,1381363200,1381449599 +2013-10-09,128.800,1381276800,1381363199 +2013-10-08,127.105,1381190400,1381276799 +2013-10-07,129.850,1381104000,1381190399 +2013-10-06,129.010,1381017600,1381103999 +2013-10-05,129.535,1380931200,1381017599 +2013-10-04,126.750,1380844800,1380931199 +2013-10-03,119.040,1380758400,1380844799 +2013-10-02,132.820,1380672000,1380758399 +2013-10-01,133.655,1380585600,1380671999 +2013-09-30,137.750,1380499200,1380585599 +2013-09-29,137.755,1380412800,1380499199 +2013-09-28,134.700,1380326400,1380412799 +2013-09-27,131.840,1380240000,1380326399 +2013-09-26,131.572,1380153600,1380239999 +2013-09-25,128.535,1380067200,1380153599 +2013-09-24,126.755,1379980800,1380067199 +2013-09-23,130.853,1379894400,1379980799 +2013-09-22,130.905,1379808000,1379894399 +2013-09-21,127.780,1379721600,1379807999 +2013-09-20,132.660,1379635200,1379721599 +2013-09-19,131.570,1379548800,1379635199 +2013-09-18,132.455,1379462400,1379548799 +2013-09-17,132.175,1379376000,1379462399 +2013-09-16,131.790,1379289600,1379375999 +2013-09-15,130.420,1379203200,1379289599 +2013-09-14,135.430,1379116800,1379203199 +2013-09-13,135.205,1379030400,1379116799 +2013-09-12,135.815,1378944000,1379030399 +2013-09-11,131.860,1378857600,1378943999 +2013-09-10,128.505,1378771200,1378857599 +2013-09-09,125.460,1378684800,1378771199 +2013-09-08,124.425,1378598400,1378684799 +2013-09-07,122.415,1378512000,1378598399 +2013-09-06,126.915,1378425600,1378511999 +2013-09-05,129.100,1378339200,1378425599 +2013-09-04,140.515,1378252800,1378339199 +2013-09-03,136.975,1378166400,1378252799 +2013-09-02,142.565,1378080000,1378166399 +2013-09-01,140.475,1377993600,1378079999 +2013-08-31,136.990,1377907200,1377993599 +2013-08-30,129.050,1377820800,1377907199 +2013-08-29,123.160,1377734400,1377820799 +2013-08-28,126.900,1377648000,1377734399 +2013-08-27,123.655,1377561600,1377647999 +2013-08-26,122.433,1377475200,1377561599 +2013-08-25,121.295,1377388800,1377475199 +2013-08-24,119.950,1377302400,1377388799 +2013-08-23,122.000,1377216000,1377302399 +2013-08-22,123.400,1377129600,1377215999 +2013-08-21,123.062,1377043200,1377129599 +2013-08-20,121.006,1376956800,1377043199 +2013-08-19,118.221,1376870400,1376956799 +2013-08-18,113.719,1376784000,1376870399 +2013-08-17,111.372,1376697600,1376783999 +2013-08-16,111.148,1376611200,1376697599 +2013-08-15,112.904,1376524800,1376611199 +2013-08-14,112.275,1376438400,1376524799 +2013-08-13,108.170,1376352000,1376438399 +2013-08-12,106.500,1376265600,1376351999 +2013-08-11,104.095,1376179200,1376265599 +2013-08-10,103.350,1376092800,1376179199 +2013-08-09,104.410,1376006400,1376092799 +2013-08-08,106.750,1375920000,1376006399 +2013-08-07,106.750,1375833600,1375919999 +2013-08-06,107.051,1375747200,1375833599 +2013-08-05,106.445,1375660800,1375747199 +2013-08-04,105.450,1375574400,1375660799 +2013-08-03,105.141,1375488000,1375574399 +2013-08-02,106.428,1375401600,1375487999 +2013-08-01,107.107,1375315200,1375401599 +2013-07-31,109.647,1375228800,1375315199 +2013-07-30,104.740,1375142400,1375228799 +2013-07-29,100.550,1375056000,1375142399 +2013-07-28,97.489,1374969600,1375055999 +2013-07-27,96.508,1374883200,1374969599 +2013-07-26,97.210,1374796800,1374883199 +2013-07-25,95.918,1374710400,1374796799 +2013-07-24,95.774,1374624000,1374710399 +2013-07-23,94.210,1374537600,1374623999 +2013-07-22,91.998,1374451200,1374537599 +2013-07-21,90.886,1374364800,1374451199 +2013-07-20,92.550,1374278400,1374364799 +2013-07-19,92.635,1374192000,1374278399 +2013-07-18,98.650,1374105600,1374191999 +2013-07-17,98.340,1374019200,1374105599 +2013-07-16,99.376,1373932800,1374019199 +2013-07-15,97.753,1373846400,1373932799 +2013-07-14,98.700,1373760000,1373846399 +2013-07-13,96.120,1373673600,1373759999 +2013-07-12,96.490,1373587200,1373673599 +2013-07-11,89.140,1373500800,1373587199 +2013-07-10,81.860,1373414400,1373500799 +2013-07-09,77.150,1373328000,1373414399 +2013-07-08,78.250,1373241600,1373327999 +2013-07-07,71.655,1373155200,1373241599 +2013-07-06,71.753,1373068800,1373155199 +2013-07-05,79.995,1372982400,1373068799 +2013-07-04,80.998,1372896000,1372982399 +2013-07-03,90.693,1372809600,1372895999 +2013-07-02,90.175,1372723200,1372809599 +2013-07-01,97.587,1372636800,1372723199 +2013-06-30,96.561,1372550400,1372636799 +2013-06-29,97.325,1372464000,1372550399 +2013-06-28,101.737,1372377600,1372463999 +2013-06-27,104.000,1372291200,1372377599 +2013-06-26,104.409,1372204800,1372291199 +2013-06-25,104.280,1372118400,1372204799 +2013-06-24,108.117,1372032000,1372118399 +2013-06-23,108.500,1371945600,1372031999 +2013-06-22,109.728,1371859200,1371945599 +2013-06-21,113.140,1371772800,1371859199 +2013-06-20,111.276,1371686400,1371772799 +2013-06-19,108.638,1371600000,1371686399 +2013-06-18,106.531,1371513600,1371599999 +2013-06-17,101.055,1371427200,1371513599 +2013-06-16,100.700,1371340800,1371427199 +2013-06-15,101.850,1371254400,1371340799 +2013-06-14,104.325,1371168000,1371254399 +2013-06-13,109.538,1371081600,1371167999 +2013-06-12,110.394,1370995200,1371081599 +2013-06-11,107.975,1370908800,1370995199 +2013-06-10,105.269,1370822400,1370908799 +2013-06-09,108.441,1370736000,1370822399 +2013-06-08,111.208,1370649600,1370735999 +2013-06-07,118.985,1370563200,1370649599 +2013-06-06,122.500,1370476800,1370563199 +2013-06-05,122.435,1370390400,1370476799 +2013-06-04,122.289,1370304000,1370390399 +2013-06-03,122.500,1370217600,1370303999 +2013-06-02,129.350,1370131200,1370217599 +2013-06-01,129.298,1370044800,1370131199 +2013-05-31,129.350,1369958400,1370044799 +2013-05-30,132.250,1369872000,1369958399 +2013-05-29,130.795,1369785600,1369871999 +2013-05-28,130.175,1369699200,1369785599 +2013-05-27,134.483,1369612800,1369699199 +2013-05-26,133.993,1369526400,1369612799 +2013-05-25,133.160,1369440000,1369526399 +2013-05-24,130.075,1369353600,1369439999 +2013-05-23,125.367,1369267200,1369353599 +2013-05-22,123.446,1369180800,1369267199 +2013-05-21,122.510,1369094400,1369180799 +2013-05-20,123.061,1369008000,1369094399 +2013-05-19,123.856,1368921600,1369007999 +2013-05-18,124.375,1368835200,1368921599 +2013-05-17,121.755,1368748800,1368835199 +2013-05-16,116.490,1368662400,1368748799 +2013-05-15,113.605,1368576000,1368662399 +2013-05-14,118.890,1368489600,1368575999 +2013-05-13,116.760,1368403200,1368489599 +2013-05-12,116.545,1368316800,1368403199 +2013-05-11,118.190,1368230400,1368316799 +2013-05-10,117.400,1368144000,1368230399 +2013-05-09,113.330,1368057600,1368143999 +2013-05-08,112.690,1367971200,1368057599 +2013-05-07,112.847,1367884800,1367971199 +2013-05-06,120.322,1367798400,1367884799 +2013-05-05,115.850,1367712000,1367798399 +2013-05-04,106.550,1367625600,1367711999 +2013-05-03,107.189,1367539200,1367625599 +2013-05-02,120.990,1367452800,1367539199 +2013-05-01,139.445,1367366400,1367452799 +2013-04-30,145.465,1367280000,1367366399 +2013-04-29,140.966,1367193600,1367279999 +2013-04-28,135.212,1367107200,1367193599 +2013-04-27,128.000,1367020800,1367107199 +2013-04-26,136.900,1366934400,1367020799 +2013-04-25,141.710,1366848000,1366934399 +2013-04-24,154.200,1366761600,1366847999 +2013-04-23,143.475,1366675200,1366761599 +2013-04-22,127.400,1366588800,1366675199 +2013-04-21,119.200,1366502400,1366588799 +2013-04-20,126.616,1366416000,1366502399 +2013-04-19,118.480,1366329600,1366415999 +2013-04-18,109.010,1366243200,1366329599 +2013-04-17,93.070,1366156800,1366243199 +2013-04-16,68.356,1366070400,1366156799 +2013-04-15,82.386,1365984000,1366070399 +2013-04-14,90.000,1365897600,1365983999 +2013-04-13,93.000,1365811200,1365897599 +2013-04-12,117.000,1365724800,1365811199 +2013-04-11,124.900,1365638400,1365724799 +2013-04-10,165.000,1365552000,1365638399 +2013-04-09,230.000,1365465600,1365551999 +2013-04-08,187.500,1365379200,1365465599 +2013-04-07,162.301,1365292800,1365379199 +2013-04-06,142.631,1365206400,1365292799 +2013-04-05,142.324,1365120000,1365206399 +2013-04-04,132.120,1365033600,1365119999 +2013-04-03,135.000,1364947200,1365033599 +2013-04-02,117.980,1364860800,1364947199 +2013-04-01,104.000,1364774400,1364860799 +2013-03-31,93.030,1364688000,1364774399 +2013-03-30,92.190,1364601600,1364687999 +2013-03-29,90.500,1364515200,1364601599 +2013-03-28,86.180,1364428800,1364515199 +2013-03-27,88.920,1364342400,1364428799 +2013-03-26,78.500,1364256000,1364342399 +2013-03-25,73.600,1364169600,1364255999 +2013-03-24,71.500,1364083200,1364169599 +2013-03-23,64.350,1363996800,1364083199 +2013-03-22,69.865,1363910400,1363996799 +2013-03-21,70.850,1363824000,1363910399 +2013-03-20,64.489,1363737600,1363823999 +2013-03-19,59.140,1363651200,1363737599 +2013-03-18,51.600,1363564800,1363651199 +2013-03-17,47.400,1363478400,1363564799 +2013-03-16,47.000,1363392000,1363478399 +2013-03-15,46.950,1363305600,1363391999 +2013-03-14,47.170,1363219200,1363305599 +2013-03-13,46.920,1363132800,1363219199 +2013-03-12,44.290,1363046400,1363132799 +2013-03-11,48.400,1362960000,1363046399 +2013-03-10,46.000,1362873600,1362959999 +2013-03-09,46.850,1362787200,1362873599 +2013-03-08,44.180,1362700800,1362787199 +2013-03-07,42.000,1362614400,1362700799 +2013-03-06,41.020,1362528000,1362614399 +2013-03-05,40.330,1362441600,1362527999 +2013-03-04,36.152,1362355200,1362441599 +2013-03-03,34.500,1362268800,1362355199 +2013-03-02,34.250,1362182400,1362268799 +2013-03-01,34.500,1362096000,1362182399 +2013-02-28,33.380,1362009600,1362095999 +2013-02-27,30.901,1361923200,1362009599 +2013-02-26,31.100,1361836800,1361923199 +2013-02-25,30.400,1361750400,1361836799 +2013-02-24,29.890,1361664000,1361750399 +2013-02-23,29.800,1361577600,1361663999 +2013-02-22,30.245,1361491200,1361577599 +2013-02-21,29.748,1361404800,1361491199 +2013-02-20,29.645,1361318400,1361404799 +2013-02-19,29.418,1361232000,1361318399 +2013-02-18,26.950,1361145600,1361231999 +2013-02-17,26.815,1361059200,1361145599 +2013-02-16,27.216,1360972800,1361059199 +2013-02-15,27.100,1360886400,1360972799 +2013-02-14,27.221,1360800000,1360886399 +2013-02-13,24.200,1360713600,1360799999 +2013-02-12,25.170,1360627200,1360713599 +2013-02-11,24.650,1360540800,1360627199 +2013-02-10,23.970,1360454400,1360540799 +2013-02-09,23.650,1360368000,1360454399 +2013-02-08,22.660,1360281600,1360367999 +2013-02-07,22.150,1360195200,1360281599 +2013-02-06,21.180,1360108800,1360195199 +2013-02-05,20.600,1360022400,1360108799 +2013-02-04,20.430,1359936000,1360022399 +2013-02-03,20.590,1359849600,1359935999 +2013-02-02,19.630,1359763200,1359849599 +2013-02-01,20.499,1359676800,1359763199 +2013-01-31,20.410,1359590400,1359676799 +2013-01-30,19.700,1359504000,1359590399 +2013-01-29,19.525,1359417600,1359503999 +2013-01-28,18.721,1359331200,1359417599 +2013-01-27,17.818,1359244800,1359331199 +2013-01-26,17.880,1359158400,1359244799 +2013-01-25,17.400,1359072000,1359158399 +2013-01-24,16.896,1358985600,1359071999 +2013-01-23,17.500,1358899200,1358985599 +2013-01-22,17.261,1358812800,1358899199 +2013-01-21,16.800,1358726400,1358812799 +2013-01-20,15.700,1358640000,1358726399 +2013-01-19,15.615,1358553600,1358639999 +2013-01-18,15.705,1358467200,1358553599 +2013-01-17,15.500,1358380800,1358467199 +2013-01-16,14.730,1358294400,1358380799 +2013-01-15,14.250,1358208000,1358294399 +2013-01-14,14.300,1358121600,1358207999 +2013-01-13,14.116,1358035200,1358121599 +2013-01-12,14.237,1357948800,1358035199 +2013-01-11,14.137,1357862400,1357948799 +2013-01-10,14.140,1357776000,1357862399 +2013-01-09,13.770,1357689600,1357775999 +2013-01-08,13.743,1357603200,1357689599 +2013-01-07,13.588,1357516800,1357603199 +2013-01-06,13.454,1357430400,1357516799 +2013-01-05,13.440,1357344000,1357430399 +2013-01-04,13.500,1357257600,1357343999 +2013-01-03,13.398,1357171200,1357257599 +2013-01-02,13.280,1357084800,1357171199 +2013-01-01,13.304,1356998400,1357084799 +2012-12-31,13.510,1356912000,1356998399 +2012-12-30,13.450,1356825600,1356911999 +2012-12-29,13.400,1356739200,1356825599 +2012-12-28,13.421,1356652800,1356739199 +2012-12-27,13.422,1356566400,1356652799 +2012-12-26,13.468,1356480000,1356566399 +2012-12-25,13.350,1356393600,1356479999 +2012-12-24,13.380,1356307200,1356393599 +2012-12-23,13.312,1356220800,1356307199 +2012-12-22,13.371,1356134400,1356220799 +2012-12-21,13.500,1356048000,1356134399 +2012-12-20,13.525,1355961600,1356047999 +2012-12-19,13.599,1355875200,1355961599 +2012-12-18,13.299,1355788800,1355875199 +2012-12-17,13.250,1355702400,1355788799 +2012-12-16,13.300,1355616000,1355702399 +2012-12-15,13.490,1355529600,1355615999 +2012-12-14,13.600,1355443200,1355529599 +2012-12-13,13.700,1355356800,1355443199 +2012-12-12,13.699,1355270400,1355356799 +2012-12-11,13.557,1355184000,1355270399 +2012-12-10,13.433,1355097600,1355183999 +2012-12-09,13.388,1355011200,1355097599 +2012-12-08,13.420,1354924800,1355011199 +2012-12-07,13.500,1354838400,1354924799 +2012-12-06,13.299,1354752000,1354838399 +2012-12-05,13.380,1354665600,1354751999 +2012-12-04,13.410,1354579200,1354665599 +2012-12-03,12.679,1354492800,1354579199 +2012-12-02,12.500,1354406400,1354492799 +2012-12-01,12.562,1354320000,1354406399 +2012-11-30,12.565,1354233600,1354319999 +2012-11-29,12.450,1354147200,1354233599 +2012-11-28,12.348,1354060800,1354147199 +2012-11-27,12.200,1353974400,1354060799 +2012-11-26,12.246,1353888000,1353974399 +2012-11-25,12.482,1353801600,1353887999 +2012-11-24,12.412,1353715200,1353801599 +2012-11-23,12.345,1353628800,1353715199 +2012-11-22,12.422,1353542400,1353628799 +2012-11-21,11.770,1353456000,1353542399 +2012-11-20,11.733,1353369600,1353455999 +2012-11-19,11.800,1353283200,1353369599 +2012-11-18,11.652,1353196800,1353283199 +2012-11-17,11.789,1353110400,1353196799 +2012-11-16,11.749,1353024000,1353110399 +2012-11-15,11.198,1352937600,1353023999 +2012-11-14,10.950,1352851200,1352937599 +2012-11-13,10.951,1352764800,1352851199 +2012-11-12,11.008,1352678400,1352764799 +2012-11-11,10.869,1352592000,1352678399 +2012-11-10,10.890,1352505600,1352591999 +2012-11-09,10.815,1352419200,1352505599 +2012-11-08,10.925,1352332800,1352419199 +2012-11-07,10.920,1352246400,1352332799 +2012-11-06,10.899,1352160000,1352246399 +2012-11-05,10.748,1352073600,1352159999 +2012-11-04,10.800,1351987200,1352073599 +2012-11-03,10.643,1351900800,1351987199 +2012-11-02,10.469,1351814400,1351900799 +2012-11-01,10.570,1351728000,1351814399 +2012-10-31,11.201,1351641600,1351727999 +2012-10-30,10.888,1351555200,1351641599 +2012-10-29,10.600,1351468800,1351555199 +2012-10-28,10.700,1351382400,1351468799 +2012-10-27,10.261,1351296000,1351382399 +2012-10-26,10.171,1351209600,1351295999 +2012-10-25,10.862,1351123200,1351209599 +2012-10-24,11.650,1351036800,1351123199 +2012-10-23,11.650,1350950400,1351036799 +2012-10-22,11.710,1350864000,1350950399 +2012-10-21,11.631,1350777600,1350863999 +2012-10-20,11.740,1350691200,1350777599 +2012-10-19,11.740,1350604800,1350691199 +2012-10-18,11.940,1350518400,1350604799 +2012-10-17,11.810,1350432000,1350518399 +2012-10-16,11.850,1350345600,1350431999 +2012-10-15,11.838,1350259200,1350345599 +2012-10-14,11.739,1350172800,1350259199 +2012-10-13,11.861,1350086400,1350172799 +2012-10-12,12.000,1350000000,1350086399 +2012-10-11,12.030,1349913600,1349999999 +2012-10-10,12.120,1349827200,1349913599 +2012-10-09,11.895,1349740800,1349827199 +2012-10-08,11.778,1349654400,1349740799 +2012-10-07,11.800,1349568000,1349654399 +2012-10-06,12.505,1349481600,1349567999 +2012-10-05,12.688,1349395200,1349481599 +2012-10-04,12.850,1349308800,1349395199 +2012-10-03,12.890,1349222400,1349308799 +2012-10-02,12.840,1349136000,1349222399 +2012-10-01,12.400,1349049600,1349135999 +2012-09-30,12.400,1348963200,1349049599 +2012-09-29,12.363,1348876800,1348963199 +2012-09-28,12.391,1348790400,1348876799 +2012-09-27,12.309,1348704000,1348790399 +2012-09-26,12.270,1348617600,1348703999 +2012-09-25,12.197,1348531200,1348617599 +2012-09-24,12.100,1348444800,1348531199 +2012-09-23,12.193,1348358400,1348444799 +2012-09-22,12.238,1348272000,1348358399 +2012-09-21,12.368,1348185600,1348271999 +2012-09-20,12.283,1348099200,1348185599 +2012-09-19,12.573,1348012800,1348099199 +2012-09-18,12.250,1347926400,1348012799 +2012-09-17,11.890,1347840000,1347926399 +2012-09-16,11.870,1347753600,1347839999 +2012-09-15,11.750,1347667200,1347753599 +2012-09-14,11.670,1347580800,1347667199 +2012-09-13,11.399,1347494400,1347580799 +2012-09-12,11.365,1347408000,1347494399 +2012-09-11,11.331,1347321600,1347407999 +2012-09-10,11.170,1347235200,1347321599 +2012-09-09,11.020,1347148800,1347235199 +2012-09-08,11.037,1347062400,1347148799 +2012-09-07,11.000,1346976000,1347062399 +2012-09-06,11.181,1346889600,1346975999 +2012-09-05,11.000,1346803200,1346889599 +2012-09-04,10.385,1346716800,1346803199 +2012-09-03,10.530,1346630400,1346716799 +2012-09-02,10.204,1346544000,1346630399 +2012-09-01,9.965,1346457600,1346543999 +2012-08-31,10.160,1346371200,1346457599 +2012-08-30,10.777,1346284800,1346371199 +2012-08-29,10.917,1346198400,1346284799 +2012-08-28,10.940,1346112000,1346198399 +2012-08-27,10.950,1346025600,1346111999 +2012-08-26,10.610,1345939200,1346025599 +2012-08-25,10.524,1345852800,1345939199 +2012-08-24,10.600,1345766400,1345852799 +2012-08-23,10.100,1345680000,1345766399 +2012-08-22,9.807,1345593600,1345679999 +2012-08-21,9.915,1345507200,1345593599 +2012-08-20,10.100,1345420800,1345507199 +2012-08-19,8.000,1345334400,1345420799 +2012-08-18,11.610,1345248000,1345334399 +2012-08-17,11.584,1345161600,1345247999 +2012-08-16,13.500,1345075200,1345161599 +2012-08-15,13.250,1344988800,1345075199 +2012-08-14,12.190,1344902400,1344988799 +2012-08-13,12.038,1344816000,1344902399 +2012-08-12,11.624,1344729600,1344815999 +2012-08-11,11.510,1344643200,1344729599 +2012-08-10,11.386,1344556800,1344643199 +2012-08-09,11.061,1344470400,1344556799 +2012-08-08,11.055,1344384000,1344470399 +2012-08-07,11.100,1344297600,1344383999 +2012-08-06,10.855,1344211200,1344297599 +2012-08-05,10.870,1344124800,1344211199 +2012-08-04,10.984,1344038400,1344124799 +2012-08-03,10.970,1343952000,1344038399 +2012-08-02,10.530,1343865600,1343951999 +2012-08-01,9.550,1343779200,1343865599 +2012-07-31,9.350,1343692800,1343779199 +2012-07-30,9.098,1343606400,1343692799 +2012-07-29,8.710,1343520000,1343606399 +2012-07-28,8.888,1343433600,1343519999 +2012-07-27,8.900,1343347200,1343433599 +2012-07-26,8.900,1343260800,1343347199 +2012-07-25,8.800,1343174400,1343260799 +2012-07-24,8.600,1343088000,1343174399 +2012-07-23,8.446,1343001600,1343087999 +2012-07-22,8.410,1342915200,1343001599 +2012-07-21,8.846,1342828800,1342915199 +2012-07-20,8.520,1342742400,1342828799 +2012-07-19,8.870,1342656000,1342742399 +2012-07-18,9.110,1342569600,1342655999 +2012-07-17,8.800,1342483200,1342569599 +2012-07-16,8.500,1342396800,1342483199 +2012-07-15,7.621,1342310400,1342396799 +2012-07-14,7.542,1342224000,1342310399 +2012-07-13,7.665,1342137600,1342223999 +2012-07-12,7.764,1342051200,1342137599 +2012-07-11,7.150,1341964800,1342051199 +2012-07-10,7.200,1341878400,1341964799 +2012-07-09,7.022,1341792000,1341878399 +2012-07-08,6.799,1341705600,1341791999 +2012-07-07,6.762,1341619200,1341705599 +2012-07-06,6.648,1341532800,1341619199 +2012-07-05,6.670,1341446400,1341532799 +2012-07-04,6.510,1341360000,1341446399 +2012-07-03,6.450,1341273600,1341359999 +2012-07-02,6.760,1341187200,1341273599 +2012-07-01,6.629,1341100800,1341187199 +2012-06-30,6.690,1341014400,1341100799 +2012-06-29,6.650,1340928000,1341014399 +2012-06-28,6.606,1340841600,1340927999 +2012-06-27,6.647,1340755200,1340841599 +2012-06-26,6.420,1340668800,1340755199 +2012-06-25,6.305,1340582400,1340668799 +2012-06-24,6.350,1340496000,1340582399 +2012-06-23,6.429,1340409600,1340495999 +2012-06-22,6.548,1340323200,1340409599 +2012-06-21,6.680,1340236800,1340323199 +2012-06-20,6.670,1340150400,1340236799 +2012-06-19,6.499,1340064000,1340150399 +2012-06-18,6.310,1339977600,1340063999 +2012-06-17,6.164,1339891200,1339977599 +2012-06-16,6.400,1339804800,1339891199 +2012-06-15,6.500,1339718400,1339804799 +2012-06-14,5.954,1339632000,1339718399 +2012-06-13,5.929,1339545600,1339631999 +2012-06-12,5.700,1339459200,1339545599 +2012-06-11,5.575,1339372800,1339459199 +2012-06-10,5.468,1339286400,1339372799 +2012-06-09,5.560,1339200000,1339286399 +2012-06-08,5.633,1339113600,1339199999 +2012-06-07,5.591,1339027200,1339113599 +2012-06-06,5.460,1338940800,1339027199 +2012-06-05,5.440,1338854400,1338940799 +2012-06-04,5.266,1338768000,1338854399 +2012-06-03,5.205,1338681600,1338767999 +2012-06-02,5.249,1338595200,1338681599 +2012-06-01,5.275,1338508800,1338595199 +2012-05-31,5.180,1338422400,1338508799 +2012-05-30,5.135,1338336000,1338422399 +2012-05-29,5.150,1338249600,1338335999 +2012-05-28,5.136,1338163200,1338249599 +2012-05-27,5.139,1338076800,1338163199 +2012-05-26,5.103,1337990400,1338076799 +2012-05-25,5.146,1337904000,1337990399 +2012-05-24,5.119,1337817600,1337903999 +2012-05-23,5.140,1337731200,1337817599 +2012-05-22,5.099,1337644800,1337731199 +2012-05-21,5.100,1337558400,1337644799 +2012-05-20,5.090,1337472000,1337558399 +2012-05-19,5.100,1337385600,1337471999 +2012-05-18,5.118,1337299200,1337385599 +2012-05-17,5.100,1337212800,1337299199 +2012-05-16,5.089,1337126400,1337212799 +2012-05-15,5.035,1337040000,1337126399 +2012-05-14,5.006,1336953600,1337039999 +2012-05-13,4.930,1336867200,1336953599 +2012-05-12,4.946,1336780800,1336867199 +2012-05-11,4.960,1336694400,1336780799 +2012-05-10,4.850,1336608000,1336694399 +2012-05-09,5.044,1336521600,1336607999 +2012-05-08,5.050,1336435200,1336521599 +2012-05-07,5.060,1336348800,1336435199 +2012-05-06,5.050,1336262400,1336348799 +2012-05-05,5.077,1336176000,1336262399 +2012-05-04,5.067,1336089600,1336175999 +2012-05-03,5.134,1336003200,1336089599 +2012-05-02,5.074,1335916800,1336003199 +2012-05-01,5.000,1335830400,1335916799 +2012-04-30,4.949,1335744000,1335830399 +2012-04-29,4.904,1335657600,1335743999 +2012-04-28,4.979,1335571200,1335657599 +2012-04-27,5.110,1335484800,1335571199 +2012-04-26,5.098,1335398400,1335484799 +2012-04-25,5.132,1335312000,1335398399 +2012-04-24,5.098,1335225600,1335311999 +2012-04-23,4.960,1335139200,1335225599 +2012-04-22,5.204,1335052800,1335139199 +2012-04-21,5.260,1334966400,1335052799 +2012-04-20,5.350,1334880000,1334966399 +2012-04-19,5.138,1334793600,1334879999 +2012-04-18,5.118,1334707200,1334793599 +2012-04-17,4.976,1334620800,1334707199 +2012-04-16,4.932,1334534400,1334620799 +2012-04-15,4.969,1334448000,1334534399 +2012-04-14,4.960,1334361600,1334447999 +2012-04-13,4.940,1334275200,1334361599 +2012-04-12,4.920,1334188800,1334275199 +2012-04-11,4.928,1334102400,1334188799 +2012-04-10,4.837,1334016000,1334102399 +2012-04-09,4.872,1333929600,1334015999 +2012-04-08,4.793,1333843200,1333929599 +2012-04-07,4.687,1333756800,1333843199 +2012-04-06,4.950,1333670400,1333756799 +2012-04-05,4.919,1333584000,1333670399 +2012-04-04,4.910,1333497600,1333583999 +2012-04-03,4.952,1333411200,1333497599 +2012-04-02,4.974,1333324800,1333411199 +2012-04-01,4.827,1333238400,1333324799 +2012-03-31,4.909,1333152000,1333238399 +2012-03-30,4.860,1333065600,1333151999 +2012-03-29,4.808,1332979200,1333065599 +2012-03-28,4.788,1332892800,1332979199 +2012-03-27,4.811,1332806400,1332892799 +2012-03-26,4.619,1332720000,1332806399 +2012-03-25,4.550,1332633600,1332719999 +2012-03-24,4.676,1332547200,1332633599 +2012-03-23,4.686,1332460800,1332547199 +2012-03-22,4.704,1332374400,1332460799 +2012-03-21,4.815,1332288000,1332374399 +2012-03-20,4.838,1332201600,1332287999 +2012-03-19,4.694,1332115200,1332201599 +2012-03-18,5.279,1332028800,1332115199 +2012-03-17,5.216,1331942400,1332028799 +2012-03-16,5.344,1331856000,1331942399 +2012-03-15,5.327,1331769600,1331855999 +2012-03-14,5.380,1331683200,1331769599 +2012-03-13,5.270,1331596800,1331683199 +2012-03-12,4.890,1331510400,1331596799 +2012-03-11,4.910,1331424000,1331510399 +2012-03-10,4.833,1331337600,1331423999 +2012-03-09,4.861,1331251200,1331337599 +2012-03-08,4.930,1331164800,1331251199 +2012-03-07,4.938,1331078400,1331164799 +2012-03-06,4.990,1330992000,1331078399 +2012-03-05,4.984,1330905600,1330991999 +2012-03-04,4.820,1330819200,1330905599 +2012-03-03,4.614,1330732800,1330819199 +2012-03-02,4.705,1330646400,1330732799 +2012-03-01,4.921,1330560000,1330646399 +2012-02-29,4.860,1330473600,1330559999 +2012-02-28,4.868,1330387200,1330473599 +2012-02-27,4.956,1330300800,1330387199 +2012-02-26,4.922,1330214400,1330300799 +2012-02-25,4.773,1330128000,1330214399 +2012-02-24,5.029,1330041600,1330127999 +2012-02-23,5.015,1329955200,1330041599 +2012-02-22,4.425,1329868800,1329955199 +2012-02-21,4.272,1329782400,1329868799 +2012-02-20,4.362,1329696000,1329782399 +2012-02-19,4.387,1329609600,1329695999 +2012-02-18,4.222,1329523200,1329609599 +2012-02-17,4.410,1329436800,1329523199 +2012-02-16,4.274,1329350400,1329436799 +2012-02-15,4.325,1329264000,1329350399 +2012-02-14,4.463,1329177600,1329263999 +2012-02-13,5.260,1329091200,1329177599 +2012-02-12,5.515,1329004800,1329091199 +2012-02-11,5.601,1328918400,1329004799 +2012-02-10,5.913,1328832000,1328918399 +2012-02-09,5.830,1328745600,1328831999 +2012-02-08,5.600,1328659200,1328745599 +2012-02-07,5.690,1328572800,1328659199 +2012-02-06,5.454,1328486400,1328572799 +2012-02-05,5.689,1328400000,1328486399 +2012-02-04,5.873,1328313600,1328399999 +2012-02-03,5.959,1328227200,1328313599 +2012-02-02,6.100,1328140800,1328227199 +2012-02-01,6.076,1328054400,1328140799 +2012-01-31,5.484,1327968000,1328054399 +2012-01-30,5.491,1327881600,1327967999 +2012-01-29,5.381,1327795200,1327881599 +2012-01-28,5.627,1327708800,1327795199 +2012-01-27,5.292,1327622400,1327708799 +2012-01-26,5.340,1327536000,1327622399 +2012-01-25,5.750,1327449600,1327535999 +2012-01-24,6.290,1327363200,1327449599 +2012-01-23,6.356,1327276800,1327363199 +2012-01-22,6.310,1327190400,1327276799 +2012-01-21,6.180,1327104000,1327190399 +2012-01-20,6.490,1327017600,1327103999 +2012-01-19,6.360,1326931200,1327017599 +2012-01-18,5.920,1326844800,1326931199 +2012-01-17,5.600,1326758400,1326844799 +2012-01-16,6.683,1326672000,1326758399 +2012-01-15,7.002,1326585600,1326671999 +2012-01-14,6.750,1326499200,1326585599 +2012-01-13,6.410,1326412800,1326499199 +2012-01-12,6.800,1326326400,1326412799 +2012-01-11,6.900,1326240000,1326326399 +2012-01-10,6.360,1326153600,1326239999 +2012-01-09,6.326,1326067200,1326153599 +2012-01-08,7.114,1325980800,1326067199 +2012-01-07,6.810,1325894400,1325980799 +2012-01-06,6.697,1325808000,1325894399 +2012-01-05,6.948,1325721600,1325807999 +2012-01-04,5.574,1325635200,1325721599 +2012-01-03,4.881,1325548800,1325635199 +2012-01-02,5.217,1325462400,1325548799 +2012-01-01,5.268,1325376000,1325462399 +2011-12-31,4.722,1325289600,1325375999 +2011-12-30,4.248,1325203200,1325289599 +2011-12-29,4.166,1325116800,1325203199 +2011-12-28,4.186,1325030400,1325116799 +2011-12-27,4.070,1324944000,1325030399 +2011-12-26,4.018,1324857600,1324943999 +2011-12-25,4.225,1324771200,1324857599 +2011-12-24,3.940,1324684800,1324771199 +2011-12-23,3.947,1324598400,1324684799 +2011-12-22,3.890,1324512000,1324598399 +2011-12-21,3.890,1324425600,1324511999 +2011-12-20,3.950,1324339200,1324425599 +2011-12-19,3.520,1324252800,1324339199 +2011-12-18,3.193,1324166400,1324252799 +2011-12-17,3.200,1324080000,1324166399 +2011-12-16,3.200,1323993600,1324079999 +2011-12-15,3.200,1323907200,1323993599 +2011-12-14,3.150,1323820800,1323907199 +2011-12-13,3.250,1323734400,1323820799 +2011-12-12,3.135,1323648000,1323734399 +2011-12-11,3.251,1323561600,1323647999 +2011-12-10,3.050,1323475200,1323561599 +2011-12-09,2.970,1323388800,1323475199 +2011-12-08,2.980,1323302400,1323388799 +2011-12-07,2.990,1323216000,1323302399 +2011-12-06,3.030,1323129600,1323215999 +2011-12-05,2.880,1323043200,1323129599 +2011-12-04,2.828,1322956800,1323043199 +2011-12-03,2.794,1322870400,1322956799 +2011-12-02,3.115,1322784000,1322870399 +2011-12-01,3.060,1322697600,1322783999 +2011-11-30,2.970,1322611200,1322697599 +2011-11-29,2.750,1322524800,1322611199 +2011-11-28,2.550,1322438400,1322524799 +2011-11-27,2.480,1322352000,1322438399 +2011-11-26,2.470,1322265600,1322351999 +2011-11-25,2.506,1322179200,1322265599 +2011-11-24,2.432,1322092800,1322179199 +2011-11-23,2.332,1322006400,1322092799 +2011-11-22,2.329,1321920000,1322006399 +2011-11-21,2.294,1321833600,1321919999 +2011-11-20,2.200,1321747200,1321833599 +2011-11-19,2.196,1321660800,1321747199 +2011-11-18,2.050,1321574400,1321660799 +2011-11-17,2.250,1321488000,1321574399 +2011-11-16,2.560,1321401600,1321487999 +2011-11-15,2.329,1321315200,1321401599 +2011-11-14,2.220,1321228800,1321315199 +2011-11-13,2.997,1321142400,1321228799 +2011-11-12,3.031,1321056000,1321142399 +2011-11-11,3.080,1320969600,1321055999 +2011-11-10,2.840,1320883200,1320969599 +2011-11-09,2.950,1320796800,1320883199 +2011-11-08,3.035,1320710400,1320796799 +2011-11-07,3.007,1320624000,1320710399 +2011-11-06,2.960,1320537600,1320623999 +2011-11-05,2.970,1320451200,1320537599 +2011-11-04,3.109,1320364800,1320451199 +2011-11-03,3.152,1320278400,1320364799 +2011-11-02,3.254,1320192000,1320278399 +2011-11-01,3.150,1320105600,1320191999 +2011-10-31,3.248,1320019200,1320105599 +2011-10-30,3.270,1319932800,1320019199 +2011-10-29,3.581,1319846400,1319932799 +2011-10-28,3.190,1319760000,1319846399 +2011-10-27,3.040,1319673600,1319759999 +2011-10-26,2.773,1319587200,1319673599 +2011-10-25,2.770,1319500800,1319587199 +2011-10-24,2.545,1319414400,1319500799 +2011-10-23,3.170,1319328000,1319414399 +2011-10-22,3.159,1319241600,1319327999 +2011-10-21,2.570,1319155200,1319241599 +2011-10-20,2.348,1319068800,1319155199 +2011-10-19,2.270,1318982400,1319068799 +2011-10-18,2.419,1318896000,1318982399 +2011-10-17,2.560,1318809600,1318895999 +2011-10-16,3.557,1318723200,1318809599 +2011-10-15,3.842,1318636800,1318723199 +2011-10-14,3.988,1318550400,1318636799 +2011-10-13,4.046,1318464000,1318550399 +2011-10-12,4.150,1318377600,1318463999 +2011-10-11,3.931,1318291200,1318377599 +2011-10-10,4.100,1318204800,1318291199 +2011-10-09,4.103,1318118400,1318204799 +2011-10-08,4.008,1318032000,1318118399 +2011-10-07,4.273,1317945600,1318031999 +2011-10-06,4.734,1317859200,1317945599 +2011-10-05,4.870,1317772800,1317859199 +2011-10-04,4.960,1317686400,1317772799 +2011-10-03,5.024,1317600000,1317686399 +2011-10-02,5.027,1317513600,1317599999 +2011-10-01,5.032,1317427200,1317513599 +2011-09-30,5.140,1317340800,1317427199 +2011-09-29,4.779,1317254400,1317340799 +2011-09-28,4.773,1317168000,1317254399 +2011-09-27,4.916,1317081600,1317167999 +2011-09-26,4.870,1316995200,1317081599 +2011-09-25,5.330,1316908800,1316995199 +2011-09-24,5.468,1316822400,1316908799 +2011-09-23,5.545,1316736000,1316822399 +2011-09-22,5.428,1316649600,1316735999 +2011-09-21,5.611,1316563200,1316649599 +2011-09-20,6.112,1316476800,1316563199 +2011-09-19,5.460,1316390400,1316476799 +2011-09-18,5.200,1316304000,1316390399 +2011-09-17,4.770,1316217600,1316303999 +2011-09-16,4.820,1316131200,1316217599 +2011-09-15,4.840,1316044800,1316131199 +2011-09-14,5.619,1315958400,1316044799 +2011-09-13,5.800,1315872000,1315958399 +2011-09-12,6.078,1315785600,1315871999 +2011-09-11,5.864,1315699200,1315785599 +2011-09-10,4.774,1315612800,1315699199 +2011-09-09,5.030,1315526400,1315612799 +2011-09-08,6.530,1315440000,1315526399 +2011-09-07,7.186,1315353600,1315439999 +2011-09-06,6.863,1315267200,1315353599 +2011-09-05,7.611,1315180800,1315267199 +2011-09-04,8.178,1315094400,1315180799 +2011-09-03,8.480,1315008000,1315094399 +2011-09-02,8.640,1314921600,1315007999 +2011-09-01,8.210,1314835200,1314921599 +2011-08-31,8.200,1314748800,1314835199 +2011-08-30,8.791,1314662400,1314748799 +2011-08-29,8.969,1314576000,1314662399 +2011-08-28,9.070,1314489600,1314575999 +2011-08-27,8.590,1314403200,1314489599 +2011-08-26,8.179,1314316800,1314403199 +2011-08-25,9.657,1314230400,1314316799 +2011-08-24,10.851,1314144000,1314230399 +2011-08-23,10.940,1314057600,1314143999 +2011-08-22,10.895,1313971200,1314057599 +2011-08-21,11.311,1313884800,1313971199 +2011-08-20,11.453,1313798400,1313884799 +2011-08-19,11.650,1313712000,1313798399 +2011-08-18,10.830,1313625600,1313711999 +2011-08-17,10.946,1313539200,1313625599 +2011-08-16,10.964,1313452800,1313539199 +2011-08-15,11.150,1313366400,1313452799 +2011-08-14,10.796,1313280000,1313366399 +2011-08-13,10.131,1313193600,1313279999 +2011-08-12,9.461,1313107200,1313193599 +2011-08-11,9.463,1313020800,1313107199 +2011-08-10,9.980,1312934400,1313020799 +2011-08-09,9.990,1312848000,1312934399 +2011-08-08,7.800,1312761600,1312847999 +2011-08-07,7.900,1312675200,1312761599 +2011-08-06,6.550,1312588800,1312675199 +2011-08-05,9.800,1312502400,1312588799 +2011-08-04,10.750,1312416000,1312502399 +2011-08-03,9.260,1312329600,1312415999 +2011-08-02,12.050,1312243200,1312329599 +2011-08-01,13.095,1312156800,1312243199 +2011-07-31,13.350,1312070400,1312156799 +2011-07-30,13.530,1311984000,1312070399 +2011-07-29,13.498,1311897600,1311983999 +2011-07-28,13.490,1311811200,1311897599 +2011-07-27,13.939,1311724800,1311811199 +2011-07-26,13.882,1311638400,1311724799 +2011-07-25,14.048,1311552000,1311638399 +2011-07-24,13.980,1311465600,1311551999 +2011-07-23,13.680,1311379200,1311465599 +2011-07-22,13.695,1311292800,1311379199 +2011-07-21,13.610,1311206400,1311292799 +2011-07-20,13.689,1311120000,1311206399 +2011-07-19,13.850,1311033600,1311119999 +2011-07-18,13.480,1310947200,1311033599 +2011-07-17,13.160,1310860800,1310947199 +2011-07-16,13.719,1310774400,1310860799 +2011-07-15,13.810,1310688000,1310774399 +2011-07-14,13.990,1310601600,1310687999 +2011-07-13,13.951,1310515200,1310601599 +2011-07-12,14.009,1310428800,1310515199 +2011-07-11,14.209,1310342400,1310428799 +2011-07-10,14.900,1310256000,1310342399 +2011-07-09,14.380,1310169600,1310255999 +2011-07-08,14.314,1310083200,1310169599 +2011-07-07,14.776,1309996800,1310083199 +2011-07-06,14.784,1309910400,1309996799 +2011-07-05,12.907,1309824000,1309910399 +2011-07-04,13.860,1309737600,1309823999 +2011-07-03,15.441,1309651200,1309737599 +2011-07-02,15.400,1309564800,1309651199 +2011-07-01,15.397,1309478400,1309564799 +2011-06-30,16.101,1309392000,1309478399 +2011-06-29,16.845,1309305600,1309391999 +2011-06-28,16.950,1309219200,1309305599 +2011-06-27,16.750,1309132800,1309219199 +2011-06-26,16.450,1309046400,1309132799 +2011-06-25,17.510,1308960000,1309046399 +2011-06-24,17.510,1308873600,1308959999 +2011-06-23,17.510,1308787200,1308873599 +2011-06-22,17.510,1308700800,1308787199 +2011-06-21,17.510,1308614400,1308700799 +2011-06-20,17.510,1308528000,1308614399 +2011-06-19,17.510,1308441600,1308527999 +2011-06-18,16.890,1308355200,1308441599 +2011-06-17,15.681,1308268800,1308355199 +2011-06-16,17.000,1308182400,1308268799 +2011-06-15,19.490,1308096000,1308182399 +2011-06-14,19.280,1308009600,1308095999 +2011-06-13,19.840,1307923200,1308009599 +2011-06-12,18.546,1307836800,1307923199 +2011-06-11,14.651,1307750400,1307836799 +2011-06-10,23.950,1307664000,1307750399 +2011-06-09,28.919,1307577600,1307663999 +2011-06-08,29.600,1307491200,1307577599 +2011-06-07,23.923,1307404800,1307491199 +2011-06-06,18.550,1307318400,1307404799 +2011-06-05,16.700,1307232000,1307318399 +2011-06-04,18.890,1307145600,1307231999 +2011-06-03,14.290,1307059200,1307145599 +2011-06-02,10.600,1306972800,1307059199 +2011-06-01,9.570,1306886400,1306972799 +2011-05-31,8.741,1306800000,1306886399 +2011-05-30,8.800,1306713600,1306799999 +2011-05-29,8.430,1306627200,1306713599 +2011-05-28,8.300,1306540800,1306627199 +2011-05-27,8.500,1306454400,1306540799 +2011-05-26,8.798,1306368000,1306454399 +2011-05-25,8.400,1306281600,1306367999 +2011-05-24,7.420,1306195200,1306281599 +2011-05-23,7.150,1306108800,1306195199 +2011-05-22,6.690,1306022400,1306108799 +2011-05-21,6.120,1305936000,1306022399 +2011-05-20,5.590,1305849600,1305935999 +2011-05-19,6.805,1305763200,1305849599 +2011-05-18,6.880,1305676800,1305763199 +2011-05-17,7.190,1305590400,1305676799 +2011-05-16,8.034,1305504000,1305590399 +2011-05-15,6.987,1305417600,1305503999 +2011-05-14,7.198,1305331200,1305417599 +2011-05-13,8.198,1305244800,1305331199 +2011-05-12,6.300,1305158400,1305244799 +2011-05-11,5.500,1305072000,1305158399 +2011-05-10,5.810,1304985600,1305071999 +2011-05-09,3.800,1304899200,1304985599 +2011-05-08,3.866,1304812800,1304899199 +2011-05-07,3.641,1304726400,1304812799 +2011-05-06,3.450,1304640000,1304726399 +2011-05-05,3.333,1304553600,1304639999 +2011-05-04,3.406,1304467200,1304553599 +2011-05-03,3.410,1304380800,1304467199 +2011-05-02,3.200,1304294400,1304380799 +2011-05-01,3.033,1304208000,1304294399 +2011-04-30,3.500,1304121600,1304207999 +2011-04-29,2.880,1304035200,1304121599 +2011-04-28,2.211,1303948800,1304035199 +2011-04-27,1.900,1303862400,1303948799 +2011-04-26,1.795,1303776000,1303862399 +2011-04-25,1.559,1303689600,1303775999 +2011-04-24,1.630,1303603200,1303689599 +2011-04-23,1.700,1303516800,1303603199 +2011-04-22,1.409,1303430400,1303516799 +2011-04-21,1.210,1303344000,1303430399 +2011-04-20,1.142,1303257600,1303343999 +2011-04-19,1.198,1303171200,1303257599 +2011-04-18,1.162,1303084800,1303171199 +2011-04-17,1.112,1302998400,1303084799 +2011-04-16,1.050,1302912000,1302998399 +2011-04-15,0.990,1302825600,1302911999 +2011-04-14,1.000,1302739200,1302825599 +2011-04-13,0.923,1302652800,1302739199 +2011-04-12,0.860,1302566400,1302652799 +2011-04-11,0.770,1302480000,1302566399 +2011-04-10,0.737,1302393600,1302479999 +2011-04-09,0.730,1302307200,1302393599 +2011-04-08,0.750,1302220800,1302307199 +2011-04-07,0.754,1302134400,1302220799 +2011-04-06,0.740,1302048000,1302134399 +2011-04-05,0.710,1301961600,1302047999 +2011-04-04,0.680,1301875200,1301961599 +2011-04-03,0.779,1301788800,1301875199 +2011-04-02,0.782,1301702400,1301788799 +2011-04-01,0.774,1301616000,1301702399 +2011-03-31,0.785,1301529600,1301615999 +2011-03-30,0.790,1301443200,1301529599 +2011-03-29,0.793,1301356800,1301443199 +2011-03-28,0.799,1301270400,1301356799 +2011-03-27,0.820,1301184000,1301270399 +2011-03-26,0.855,1301097600,1301183999 +2011-03-25,0.884,1301011200,1301097599 +2011-03-24,0.867,1300924800,1301011199 +2011-03-23,0.850,1300838400,1300924799 +2011-03-22,0.809,1300752000,1300838399 +2011-03-21,0.759,1300665600,1300751999 +2011-03-20,0.741,1300579200,1300665599 +2011-03-19,0.765,1300492800,1300579199 +2011-03-18,0.817,1300406400,1300492799 +2011-03-17,0.825,1300320000,1300406399 +2011-03-16,0.860,1300233600,1300319999 +2011-03-15,0.870,1300147200,1300233599 +2011-03-14,0.895,1300060800,1300147199 +2011-03-13,0.893,1299974400,1300060799 +2011-03-12,0.918,1299888000,1299974399 +2011-03-11,0.880,1299801600,1299887999 +2011-03-10,0.933,1299715200,1299801599 +2011-03-09,0.865,1299628800,1299715199 +2011-03-08,0.870,1299542400,1299628799 +2011-03-07,0.885,1299456000,1299542399 +2011-03-06,0.900,1299369600,1299455999 +2011-03-05,0.910,1299283200,1299369599 +2011-03-04,0.901,1299196800,1299283199 +2011-03-03,0.939,1299110400,1299196799 +2011-03-02,0.940,1299024000,1299110399 +2011-03-01,0.920,1298937600,1299023999 +2011-02-28,0.860,1298851200,1298937599 +2011-02-27,0.890,1298764800,1298851199 +2011-02-26,0.958,1298678400,1298764799 +2011-02-25,0.911,1298592000,1298678399 +2011-02-24,0.997,1298505600,1298591999 +2011-02-23,0.900,1298419200,1298505599 +2011-02-22,0.870,1298332800,1298419199 +2011-02-21,0.835,1298246400,1298332799 +2011-02-20,0.850,1298160000,1298246399 +2011-02-19,0.949,1298073600,1298159999 +2011-02-18,0.899,1297987200,1298073599 +2011-02-17,1.040,1297900800,1297987199 +2011-02-16,1.045,1297814400,1297900799 +2011-02-15,1.050,1297728000,1297814399 +2011-02-14,1.070,1297641600,1297727999 +2011-02-13,1.050,1297555200,1297641599 +2011-02-12,1.080,1297468800,1297555199 +2011-02-11,1.070,1297382400,1297468799 +2011-02-10,0.980,1297296000,1297382399 +2011-02-09,1.090,1297209600,1297295999 +2011-02-08,0.918,1297123200,1297209599 +2011-02-07,0.890,1297036800,1297123199 +2011-02-06,0.900,1296950400,1297036799 +2011-02-05,0.920,1296864000,1296950399 +2011-02-04,0.811,1296777600,1296863999 +2011-02-03,0.690,1296691200,1296777599 +2011-02-02,0.716,1296604800,1296691199 +2011-02-01,0.700,1296518400,1296604799 +2011-01-31,0.520,1296432000,1296518399 +2011-01-30,0.480,1296345600,1296431999 +2011-01-29,0.439,1296259200,1296345599 +2011-01-28,0.446,1296172800,1296259199 +2011-01-27,0.421,1296086400,1296172799 +2011-01-26,0.417,1296000000,1296086399 +2011-01-25,0.410,1295913600,1295999999 +2011-01-24,0.420,1295827200,1295913599 +2011-01-23,0.442,1295740800,1295827199 +2011-01-22,0.444,1295654400,1295740799 +2011-01-21,0.420,1295568000,1295654399 +2011-01-20,0.390,1295481600,1295567999 +2011-01-19,0.313,1295395200,1295481599 +2011-01-18,0.313,1295308800,1295395199 +2011-01-17,0.350,1295222400,1295308799 +2011-01-16,0.387,1295136000,1295222399 +2011-01-15,0.386,1295049600,1295135999 +2011-01-14,0.400,1294963200,1295049599 +2011-01-13,0.318,1294876800,1294963199 +2011-01-12,0.319,1294790400,1294876799 +2011-01-11,0.327,1294704000,1294790399 +2011-01-10,0.327,1294617600,1294703999 +2011-01-09,0.323,1294531200,1294617599 +2011-01-08,0.323,1294444800,1294531199 +2011-01-07,0.320,1294358400,1294444799 +2011-01-06,0.298,1294272000,1294358399 +2011-01-05,0.299,1294185600,1294271999 +2011-01-04,0.299,1294099200,1294185599 +2011-01-03,0.295,1294012800,1294099199 +2011-01-02,0.300,1293926400,1294012799 +2011-01-01,0.300,1293840000,1293926399 +2010-12-31,0.300,1293753600,1293839999 +2010-12-30,0.300,1293667200,1293753599 +2010-12-29,0.300,1293580800,1293667199 +2010-12-28,0.281,1293494400,1293580799 +2010-12-27,0.265,1293408000,1293494399 +2010-12-26,0.265,1293321600,1293407999 +2010-12-25,0.250,1293235200,1293321599 +2010-12-24,0.248,1293148800,1293235199 +2010-12-23,0.250,1293062400,1293148799 +2010-12-22,0.250,1292976000,1293062399 +2010-12-21,0.240,1292889600,1292975999 +2010-12-20,0.267,1292803200,1292889599 +2010-12-19,0.240,1292716800,1292803199 +2010-12-18,0.241,1292630400,1292716799 +2010-12-17,0.240,1292544000,1292630399 +2010-12-16,0.250,1292457600,1292543999 +2010-12-15,0.238,1292371200,1292457599 +2010-12-14,0.247,1292284800,1292371199 +2010-12-13,0.230,1292198400,1292284799 +2010-12-12,0.220,1292112000,1292198399 +2010-12-11,0.228,1292025600,1292111999 +2010-12-10,0.204,1291939200,1292025599 +2010-12-09,0.200,1291852800,1291939199 +2010-12-08,0.239,1291766400,1291852799 +2010-12-07,0.233,1291680000,1291766399 +2010-12-06,0.204,1291593600,1291679999 +2010-12-05,0.190,1291507200,1291593599 +2010-12-04,0.205,1291420800,1291507199 +2010-12-03,0.251,1291334400,1291420799 +2010-12-02,0.255,1291248000,1291334399 +2010-12-01,0.228,1291161600,1291247999 +2010-11-30,0.208,1291075200,1291161599 +2010-11-29,0.230,1290988800,1291075199 +2010-11-28,0.270,1290902400,1290988799 +2010-11-27,0.283,1290816000,1290902399 +2010-11-26,0.284,1290729600,1290815999 +2010-11-25,0.280,1290643200,1290729599 +2010-11-24,0.283,1290556800,1290643199 +2010-11-23,0.283,1290470400,1290556799 +2010-11-22,0.288,1290384000,1290470399 +2010-11-21,0.277,1290297600,1290383999 +2010-11-20,0.283,1290211200,1290297599 +2010-11-19,0.280,1290124800,1290211199 +2010-11-18,0.268,1290038400,1290124799 +2010-11-17,0.230,1289952000,1290038399 +2010-11-16,0.223,1289865600,1289951999 +2010-11-15,0.268,1289779200,1289865599 +2010-11-14,0.279,1289692800,1289779199 +2010-11-13,0.276,1289606400,1289692799 +2010-11-12,0.268,1289520000,1289606399 +2010-11-11,0.223,1289433600,1289519999 +2010-11-10,0.240,1289347200,1289433599 +2010-11-09,0.210,1289260800,1289347199 +2010-11-08,0.243,1289174400,1289260799 +2010-11-07,0.340,1289088000,1289174399 +2010-11-06,0.390,1289001600,1289087999 +2010-11-05,0.260,1288915200,1289001599 +2010-11-04,0.230,1288828800,1288915199 +2010-11-03,0.193,1288742400,1288828799 +2010-11-02,0.194,1288656000,1288742399 +2010-11-01,0.196,1288569600,1288655999 +2010-10-31,0.193,1288483200,1288569599 +2010-10-30,0.199,1288396800,1288483199 +2010-10-29,0.190,1288310400,1288396799 +2010-10-28,0.173,1288224000,1288310399 +2010-10-27,0.188,1288137600,1288223999 +2010-10-26,0.150,1288051200,1288137599 +2010-10-25,0.132,1287964800,1288051199 +2010-10-24,0.115,1287878400,1287964799 +2010-10-23,0.106,1287792000,1287878399 +2010-10-22,0.103,1287705600,1287791999 +2010-10-21,0.107,1287619200,1287705599 +2010-10-20,0.099,1287532800,1287619199 +2010-10-19,0.097,1287446400,1287532799 +2010-10-18,0.102,1287360000,1287446399 +2010-10-17,0.102,1287273600,1287359999 +2010-10-16,0.101,1287187200,1287273599 +2010-10-15,0.105,1287100800,1287187199 +2010-10-14,0.102,1287014400,1287100799 +2010-10-13,0.105,1286928000,1287014399 +2010-10-12,0.095,1286841600,1286927999 +2010-10-11,0.095,1286755200,1286841599 +2010-10-10,0.097,1286668800,1286755199 +2010-10-09,0.094,1286582400,1286668799 +2010-10-08,0.087,1286496000,1286582399 +2010-10-07,0.067,1286409600,1286495999 +2010-10-06,0.063,1286323200,1286409599 +2010-10-05,0.061,1286236800,1286323199 +2010-10-04,0.061,1286150400,1286236799 +2010-10-03,0.061,1286064000,1286150399 +2010-10-02,0.061,1285977600,1286063999 +2010-10-01,0.062,1285891200,1285977599 +2010-09-30,0.062,1285804800,1285891199 +2010-09-29,0.062,1285718400,1285804799 +2010-09-28,0.062,1285632000,1285718399 +2010-09-27,0.062,1285545600,1285631999 +2010-09-26,0.062,1285459200,1285545599 +2010-09-25,0.062,1285372800,1285459199 +2010-09-24,0.062,1285286400,1285372799 +2010-09-23,0.062,1285200000,1285286399 +2010-09-22,0.062,1285113600,1285199999 +2010-09-21,0.063,1285027200,1285113599 +2010-09-20,0.062,1284940800,1285027199 +2010-09-19,0.063,1284854400,1284940799 +2010-09-18,0.061,1284768000,1284854399 +2010-09-17,0.059,1284681600,1284767999 +2010-09-16,0.062,1284595200,1284681599 +2010-09-15,0.060,1284508800,1284595199 +2010-09-14,0.062,1284422400,1284508799 +2010-09-13,0.062,1284336000,1284422399 +2010-09-12,0.062,1284249600,1284335999 +2010-09-11,0.064,1284163200,1284249599 +2010-09-10,0.062,1284076800,1284163199 +2010-09-09,0.061,1283990400,1284076799 +2010-09-08,0.062,1283904000,1283990399 +2010-09-07,0.061,1283817600,1283903999 +2010-09-06,0.062,1283731200,1283817599 +2010-09-05,0.062,1283644800,1283731199 +2010-09-04,0.062,1283558400,1283644799 +2010-09-03,0.061,1283472000,1283558399 +2010-09-02,0.063,1283385600,1283471999 +2010-09-01,0.063,1283299200,1283385599 +2010-08-31,0.060,1283212800,1283299199 +2010-08-30,0.065,1283126400,1283212799 +2010-08-29,0.064,1283040000,1283126399 +2010-08-28,0.064,1282953600,1283039999 +2010-08-27,0.065,1282867200,1282953599 +2010-08-26,0.064,1282780800,1282867199 +2010-08-25,0.065,1282694400,1282780799 +2010-08-24,0.065,1282608000,1282694399 +2010-08-23,0.065,1282521600,1282607999 +2010-08-22,0.066,1282435200,1282521599 +2010-08-21,0.066,1282348800,1282435199 +2010-08-20,0.066,1282262400,1282348799 +2010-08-19,0.067,1282176000,1282262399 +2010-08-18,0.068,1282089600,1282175999 +2010-08-17,0.070,1282003200,1282089599 +2010-08-16,0.066,1281916800,1282003199 +2010-08-15,0.065,1281830400,1281916799 +2010-08-14,0.067,1281744000,1281830399 +2010-08-13,0.065,1281657600,1281743999 +2010-08-12,0.070,1281571200,1281657599 +2010-08-11,0.067,1281484800,1281571199 +2010-08-10,0.070,1281398400,1281484799 +2010-08-09,0.071,1281312000,1281398399 +2010-08-08,0.061,1281225600,1281311999 +2010-08-07,0.059,1281139200,1281225599 +2010-08-06,0.062,1281052800,1281139199 +2010-08-05,0.061,1280966400,1281052799 +2010-08-04,0.057,1280880000,1280966399 +2010-08-03,0.060,1280793600,1280879999 +2010-08-02,0.060,1280707200,1280793599 +2010-08-01,0.061,1280620800,1280707199 +2010-07-31,0.068,1280534400,1280620799 +2010-07-30,0.063,1280448000,1280534399 +2010-07-29,0.070,1280361600,1280447999 +2010-07-28,0.059,1280275200,1280361599 +2010-07-27,0.060,1280188800,1280275199 +2010-07-26,0.056,1280102400,1280188799 +2010-07-25,0.051,1280016000,1280102399 +2010-07-24,0.055,1279929600,1280015999 +2010-07-23,0.063,1279843200,1279929599 +2010-07-22,0.051,1279756800,1279843199 +2010-07-21,0.079,1279670400,1279756799 +2010-07-20,0.075,1279584000,1279670399 +2010-07-19,0.081,1279497600,1279583999 +2010-07-18,0.086,1279411200,1279497599 +2010-07-17,0.050,1279324800,1279411199 +2010-07-16,0.000,1279238400,1279324799 +2010-07-15,0.000,1279152000,1279238399 +2010-07-14,0.000,1279065600,1279151999 +2010-07-13,0.000,1278979200,1279065599 +2010-07-12,0.000,1278892800,1278979199 +2010-07-11,0.000,1278806400,1278892799 +2010-07-10,0.000,1278720000,1278806399 +2010-07-09,0.000,1278633600,1278719999 +2010-07-08,0.000,1278547200,1278633599 +2010-07-07,0.000,1278460800,1278547199 +2010-07-06,0.000,1278374400,1278460799 +2010-07-05,0.000,1278288000,1278374399 +2010-07-04,0.000,1278201600,1278287999 +2010-07-03,0.000,1278115200,1278201599 +2010-07-02,0.000,1278028800,1278115199 +2010-07-01,0.000,1277942400,1278028799 +2010-06-30,0.000,1277856000,1277942399 +2010-06-29,0.000,1277769600,1277855999 +2010-06-28,0.000,1277683200,1277769599 +2010-06-27,0.000,1277596800,1277683199 +2010-06-26,0.000,1277510400,1277596799 +2010-06-25,0.000,1277424000,1277510399 +2010-06-24,0.000,1277337600,1277423999 +2010-06-23,0.000,1277251200,1277337599 +2010-06-22,0.000,1277164800,1277251199 +2010-06-21,0.000,1277078400,1277164799 +2010-06-20,0.000,1276992000,1277078399 +2010-06-19,0.000,1276905600,1276991999 +2010-06-18,0.000,1276819200,1276905599 +2010-06-17,0.000,1276732800,1276819199 +2010-06-16,0.000,1276646400,1276732799 +2010-06-15,0.000,1276560000,1276646399 +2010-06-14,0.000,1276473600,1276559999 +2010-06-13,0.000,1276387200,1276473599 +2010-06-12,0.000,1276300800,1276387199 +2010-06-11,0.000,1276214400,1276300799 +2010-06-10,0.000,1276128000,1276214399 +2010-06-09,0.000,1276041600,1276127999 +2010-06-08,0.000,1275955200,1276041599 +2010-06-07,0.000,1275868800,1275955199 +2010-06-06,0.000,1275782400,1275868799 +2010-06-05,0.000,1275696000,1275782399 +2010-06-04,0.004,1275609600,1275695999 +2010-06-03,0.000,1275523200,1275609599 +2010-06-02,0.000,1275436800,1275523199 +2010-06-01,0.000,1275350400,1275436799 +2010-05-31,0.000,1275264000,1275350399 +2010-05-30,0.004,1275177600,1275263999 +2010-05-29,0.004,1275091200,1275177599 +2010-05-28,0.004,1275004800,1275091199 +2010-05-27,0.004,1274918400,1275004799 +2010-05-26,0.004,1274832000,1274918399 +2010-05-25,0.004,1274745600,1274831999 +2010-05-24,0.000,1274659200,1274745599 +2010-05-23,0.004,1274572800,1274659199 +2010-05-22,0.004,1274486400,1274572799 +2010-05-21,0.000,1274400000,1274486399 +2010-05-20,0.004,1274313600,1274399999 +2010-05-19,0.004,1274227200,1274313599 +2010-05-18,0.004,1274140800,1274227199 +2010-05-17,0.000,1274054400,1274140799 +2010-05-16,0.000,1273968000,1274054399 +2010-05-15,0.000,1273881600,1273967999 +2010-05-14,0.004,1273795200,1273881599 +2010-05-13,0.000,1273708800,1273795199 +2010-05-12,0.004,1273622400,1273708799 +2010-05-11,0.003,1273536000,1273622399 +2010-05-10,0.003,1273449600,1273535999 +2010-05-09,0.000,1273363200,1273449599 +2010-05-08,0.003,1273276800,1273363199 +2010-05-07,0.003,1273190400,1273276799 +2010-05-06,0.003,1273104000,1273190399 +2010-05-05,0.003,1273017600,1273103999 +2010-05-04,0.003,1272931200,1273017599 +2010-05-03,0.003,1272844800,1272931199 +2010-05-02,0.003,1272758400,1272844799 +2010-05-01,0.003,1272672000,1272758399 +2010-04-30,0.003,1272585600,1272671999 +2010-04-29,0.003,1272499200,1272585599 +2010-04-28,0.002,1272412800,1272499199 +2010-04-27,0.000,1272326400,1272412799 +2010-04-26,0.003,1272240000,1272326399 +2010-04-25,0.004,1272153600,1272239999 +2010-04-24,0.000,1272067200,1272153599 +2010-04-23,0.000,1271980800,1272067199 +2010-04-22,0.005,1271894400,1271980799 +2010-04-21,0.005,1271808000,1271894399 +2010-04-20,0.005,1271721600,1271807999 +2010-04-19,0.005,1271635200,1271721599 +2010-04-18,0.000,1271548800,1271635199 +2010-04-17,0.000,1271462400,1271548799 +2010-04-16,0.004,1271376000,1271462399 +2010-04-15,0.000,1271289600,1271375999 +2010-04-14,0.000,1271203200,1271289599 +2010-04-13,0.000,1271116800,1271203199 +2010-04-12,0.000,1271030400,1271116799 +2010-04-11,0.000,1270944000,1271030399 +2010-04-10,0.000,1270857600,1270943999 +2010-04-09,0.000,1270771200,1270857599 +2010-04-08,0.005,1270684800,1270771199 +2010-04-07,0.005,1270598400,1270684799 +2010-04-06,0.000,1270512000,1270598399 +2010-04-05,0.000,1270425600,1270511999 +2010-04-04,0.000,1270339200,1270425599 +2010-04-03,0.006,1270252800,1270339199 +2010-04-02,0.000,1270166400,1270252799 +2010-04-01,0.000,1270080000,1270166399 +2010-03-31,0.006,1269993600,1270079999 +2010-03-30,0.000,1269907200,1269993599 +2010-03-29,0.000,1269820800,1269907199 +2010-03-28,0.006,1269734400,1269820799 +2010-03-27,0.006,1269648000,1269734399 +2010-03-26,0.000,1269561600,1269647999 +2010-03-25,0.006,1269475200,1269561599 +2010-03-24,0.006,1269388800,1269475199 +2010-03-23,0.005,1269302400,1269388799 +2010-03-22,0.005,1269216000,1269302399 +2010-03-21,0.007,1269129600,1269215999 +2010-03-20,0.006,1269043200,1269129599 +2010-03-19,0.006,1268956800,1269043199 +2010-03-18,0.007,1268870400,1268956799 +2010-03-17,0.006,1268784000,1268870399 +2010-03-16,0.000,1268697600,1268783999 +2010-03-15,0.000,1268611200,1268697599 +2010-03-14,0.000,1268524800,1268611199 +2010-03-13,0.000,1268438400,1268524799 +2010-03-12,0.000,1268352000,1268438399 +2010-03-11,0.000,1268265600,1268351999 +2010-03-10,0.000,1268179200,1268265599 +2010-03-09,0.000,1268092800,1268179199 +2010-03-08,0.000,1268006400,1268092799 +2010-03-07,0.000,1267920000,1268006399 +2010-03-06,0.000,1267833600,1267919999 +2010-03-05,0.000,1267747200,1267833599 +2010-03-04,0.000,1267660800,1267747199 +2010-03-03,0.000,1267574400,1267660799 +2010-03-02,0.000,1267488000,1267574399 +2010-03-01,0.000,1267401600,1267487999 +2010-02-28,0.000,1267315200,1267401599 +2010-02-27,0.000,1267228800,1267315199 +2010-02-26,0.000,1267142400,1267228799 +2010-02-25,0.000,1267056000,1267142399 +2010-02-24,0.000,1266969600,1267055999 +2010-02-23,0.000,1266883200,1266969599 +2010-02-22,0.000,1266796800,1266883199 +2010-02-21,0.000,1266710400,1266796799 +2010-02-20,0.000,1266624000,1266710399 +2010-02-19,0.000,1266537600,1266623999 +2010-02-18,0.000,1266451200,1266537599 +2010-02-17,0.000,1266364800,1266451199 +2010-02-16,0.000,1266278400,1266364799 +2010-02-15,0.000,1266192000,1266278399 +2010-02-14,0.000,1266105600,1266191999 +2010-02-13,0.000,1266019200,1266105599 +2010-02-12,0.000,1265932800,1266019199 +2010-02-11,0.000,1265846400,1265932799 +2010-02-10,0.000,1265760000,1265846399 +2010-02-09,0.000,1265673600,1265759999 +2010-02-08,0.000,1265587200,1265673599 +2010-02-07,0.000,1265500800,1265587199 +2010-02-06,0.000,1265414400,1265500799 +2010-02-05,0.000,1265328000,1265414399 +2010-02-04,0.000,1265241600,1265327999 +2010-02-03,0.000,1265155200,1265241599 +2010-02-02,0.000,1265068800,1265155199 +2010-02-01,0.000,1264982400,1265068799 +2010-01-31,0.000,1264896000,1264982399 +2010-01-30,0.000,1264809600,1264895999 +2010-01-29,0.000,1264723200,1264809599 +2010-01-28,0.000,1264636800,1264723199 +2010-01-27,0.000,1264550400,1264636799 +2010-01-26,0.000,1264464000,1264550399 +2010-01-25,0.000,1264377600,1264463999 +2010-01-24,0.000,1264291200,1264377599 +2010-01-23,0.000,1264204800,1264291199 +2010-01-22,0.000,1264118400,1264204799 +2010-01-21,0.000,1264032000,1264118399 +2010-01-20,0.000,1263945600,1264031999 +2010-01-19,0.000,1263859200,1263945599 +2010-01-18,0.000,1263772800,1263859199 +2010-01-17,0.000,1263686400,1263772799 +2010-01-16,0.000,1263600000,1263686399 +2010-01-15,0.000,1263513600,1263599999 +2010-01-14,0.000,1263427200,1263513599 +2010-01-13,0.000,1263340800,1263427199 +2010-01-12,0.000,1263254400,1263340799 +2010-01-11,0.000,1263168000,1263254399 +2010-01-10,0.000,1263081600,1263167999 +2010-01-09,0.000,1262995200,1263081599 +2010-01-08,0.000,1262908800,1262995199 +2010-01-07,0.000,1262822400,1262908799 +2010-01-06,0.000,1262736000,1262822399 +2010-01-05,0.000,1262649600,1262735999 +2010-01-04,0.000,1262563200,1262649599 +2010-01-03,0.000,1262476800,1262563199 +2010-01-02,0.000,1262390400,1262476799 +2010-01-01,0.000,1262304000,1262390399 +2009-12-31,0.000,1262217600,1262303999 +2009-12-30,0.000,1262131200,1262217599 +2009-12-29,0.000,1262044800,1262131199 +2009-12-28,0.000,1261958400,1262044799 +2009-12-27,0.000,1261872000,1261958399 +2009-12-26,0.000,1261785600,1261871999 +2009-12-25,0.000,1261699200,1261785599 +2009-12-24,0.000,1261612800,1261699199 +2009-12-23,0.000,1261526400,1261612799 +2009-12-22,0.000,1261440000,1261526399 +2009-12-21,0.000,1261353600,1261439999 +2009-12-20,0.000,1261267200,1261353599 +2009-12-19,0.000,1261180800,1261267199 +2009-12-18,0.000,1261094400,1261180799 +2009-12-17,0.000,1261008000,1261094399 +2009-12-16,0.000,1260921600,1261007999 +2009-12-15,0.000,1260835200,1260921599 +2009-12-14,0.000,1260748800,1260835199 +2009-12-13,0.000,1260662400,1260748799 +2009-12-12,0.000,1260576000,1260662399 +2009-12-11,0.000,1260489600,1260575999 +2009-12-10,0.000,1260403200,1260489599 +2009-12-09,0.000,1260316800,1260403199 +2009-12-08,0.000,1260230400,1260316799 +2009-12-07,0.000,1260144000,1260230399 +2009-12-06,0.000,1260057600,1260143999 +2009-12-05,0.000,1259971200,1260057599 +2009-12-04,0.000,1259884800,1259971199 +2009-12-03,0.000,1259798400,1259884799 +2009-12-02,0.000,1259712000,1259798399 +2009-12-01,0.000,1259625600,1259711999 +2009-11-30,0.000,1259539200,1259625599 +2009-11-29,0.000,1259452800,1259539199 +2009-11-28,0.000,1259366400,1259452799 +2009-11-27,0.000,1259280000,1259366399 +2009-11-26,0.000,1259193600,1259279999 +2009-11-25,0.000,1259107200,1259193599 +2009-11-24,0.000,1259020800,1259107199 +2009-11-23,0.001,1258934400,1259020799 +2009-11-22,0.001,1258848000,1258934399 +2009-11-21,0.001,1258761600,1258847999 +2009-11-20,0.001,1258675200,1258761599 +2009-11-19,0.001,1258588800,1258675199 +2009-11-18,0.001,1258502400,1258588799 +2009-11-17,0.001,1258416000,1258502399 +2009-11-16,0.001,1258329600,1258415999 +2009-11-15,0.001,1258243200,1258329599 +2009-11-14,0.001,1258156800,1258243199 +2009-11-13,0.001,1258070400,1258156799 +2009-11-12,0.001,1257984000,1258070399 +2009-11-11,0.001,1257897600,1257983999 +2009-11-10,0.001,1257811200,1257897599 +2009-11-09,0.001,1257724800,1257811199 +2009-11-08,0.001,1257638400,1257724799 +2009-11-07,0.001,1257552000,1257638399 +2009-11-06,0.001,1257465600,1257551999 +2009-11-05,0.001,1257379200,1257465599 +2009-11-04,0.001,1257292800,1257379199 +2009-11-03,0.001,1257206400,1257292799 +2009-11-02,0.001,1257120000,1257206399 +2009-11-01,0.001,1257033600,1257119999 +2009-10-31,0.001,1256947200,1257033599 +2009-10-30,0.001,1256860800,1256947199 +2009-10-29,0.001,1256774400,1256860799 +2009-10-28,0.001,1256688000,1256774399 +2009-10-27,0.001,1256601600,1256687999 +2009-10-26,0.001,1256515200,1256601599 +2009-10-25,0.001,1256428800,1256515199 +2009-10-24,0.001,1256342400,1256428799 +2009-10-23,0.001,1256256000,1256342399 +2009-10-22,0.001,1256169600,1256255999 +2009-10-21,0.001,1256083200,1256169599 +2009-10-20,0.001,1255996800,1256083199 +2009-10-19,0.001,1255910400,1255996799 +2009-10-18,0.001,1255824000,1255910399 +2009-10-17,0.001,1255737600,1255823999 +2009-10-16,0.001,1255651200,1255737599 +2009-10-15,0.001,1255564800,1255651199 +2009-10-14,0.001,1255478400,1255564799 +2009-10-13,0.001,1255392000,1255478399 +2009-10-12,0.001,1255305600,1255391999 +2009-10-11,0.001,1255219200,1255305599 +2009-10-10,0.001,1255132800,1255219199 +2009-10-09,0.001,1255046400,1255132799 +2009-10-08,0.001,1254960000,1255046399 +2009-10-07,0.001,1254873600,1254959999 +2009-10-06,0.000,1254787200,1254873599 +2009-10-05,0.000,1254700800,1254787199 +2009-10-04,0.000,1254614400,1254700799 +2009-10-03,0.000,1254528000,1254614399 +2009-10-02,0.000,1254441600,1254527999 +2009-10-01,0.000,1254355200,1254441599 +2009-09-30,0.000,1254268800,1254355199 +2009-09-29,0.000,1254182400,1254268799 +2009-09-28,0.000,1254096000,1254182399 +2009-09-27,0.000,1254009600,1254095999 +2009-09-26,0.000,1253923200,1254009599 +2009-09-25,0.000,1253836800,1253923199 +2009-09-24,0.000,1253750400,1253836799 +2009-09-23,0.000,1253664000,1253750399 +2009-09-22,0.000,1253577600,1253663999 +2009-09-21,0.000,1253491200,1253577599 +2009-09-20,0.000,1253404800,1253491199 +2009-09-19,0.000,1253318400,1253404799 +2009-09-18,0.000,1253232000,1253318399 +2009-09-17,0.000,1253145600,1253231999 +2009-09-16,0.000,1253059200,1253145599 +2009-09-15,0.000,1252972800,1253059199 +2009-09-14,0.000,1252886400,1252972799 +2009-09-13,0.000,1252800000,1252886399 +2009-09-12,0.000,1252713600,1252799999 +2009-09-11,0.000,1252627200,1252713599 +2009-09-10,0.000,1252540800,1252627199 +2009-09-09,0.000,1252454400,1252540799 +2009-09-08,0.000,1252368000,1252454399 +2009-09-07,0.000,1252281600,1252367999 +2009-09-06,0.000,1252195200,1252281599 +2009-09-05,0.000,1252108800,1252195199 +2009-09-04,0.000,1252022400,1252108799 +2009-09-03,0.000,1251936000,1252022399 +2009-09-02,0.000,1251849600,1251935999 +2009-09-01,0.000,1251763200,1251849599 +2009-08-31,0.000,1251676800,1251763199 +2009-08-30,0.000,1251590400,1251676799 +2009-08-29,0.000,1251504000,1251590399 +2009-08-28,0.000,1251417600,1251503999 +2009-08-27,0.000,1251331200,1251417599 +2009-08-26,0.000,1251244800,1251331199 +2009-08-25,0.000,1251158400,1251244799 +2009-08-24,0.000,1251072000,1251158399 +2009-08-23,0.000,1250985600,1251071999 +2009-08-22,0.000,1250899200,1250985599 +2009-08-21,0.000,1250812800,1250899199 +2009-08-20,0.000,1250726400,1250812799 +2009-08-19,0.000,1250640000,1250726399 +2009-08-18,0.000,1250553600,1250639999 +2009-08-17,0.000,1250467200,1250553599 +2009-08-16,0.000,1250380800,1250467199 +2009-08-15,0.000,1250294400,1250380799 +2009-08-14,0.000,1250208000,1250294399 +2009-08-13,0.000,1250121600,1250207999 +2009-08-12,0.000,1250035200,1250121599 +2009-08-11,0.000,1249948800,1250035199 +2009-08-10,0.000,1249862400,1249948799 +2009-08-09,0.000,1249776000,1249862399 +2009-08-08,0.000,1249689600,1249775999 +2009-08-07,0.000,1249603200,1249689599 +2009-08-06,0.000,1249516800,1249603199 +2009-08-05,0.000,1249430400,1249516799 +2009-08-04,0.000,1249344000,1249430399 +2009-08-03,0.000,1249257600,1249343999 +2009-08-02,0.000,1249171200,1249257599 +2009-08-01,0.000,1249084800,1249171199 +2009-07-31,0.000,1248998400,1249084799 +2009-07-30,0.000,1248912000,1248998399 +2009-07-29,0.000,1248825600,1248911999 +2009-07-28,0.000,1248739200,1248825599 +2009-07-27,0.000,1248652800,1248739199 +2009-07-26,0.000,1248566400,1248652799 +2009-07-25,0.000,1248480000,1248566399 +2009-07-24,0.000,1248393600,1248479999 +2009-07-23,0.000,1248307200,1248393599 +2009-07-22,0.000,1248220800,1248307199 +2009-07-21,0.000,1248134400,1248220799 +2009-07-20,0.000,1248048000,1248134399 +2009-07-19,0.000,1247961600,1248047999 +2009-07-18,0.000,1247875200,1247961599 +2009-07-17,0.000,1247788800,1247875199 +2009-07-16,0.000,1247702400,1247788799 +2009-07-15,0.000,1247616000,1247702399 +2009-07-14,0.000,1247529600,1247615999 +2009-07-13,0.000,1247443200,1247529599 +2009-07-12,0.000,1247356800,1247443199 +2009-07-11,0.000,1247270400,1247356799 +2009-07-10,0.000,1247184000,1247270399 +2009-07-09,0.000,1247097600,1247183999 +2009-07-08,0.000,1247011200,1247097599 +2009-07-07,0.000,1246924800,1247011199 +2009-07-06,0.000,1246838400,1246924799 +2009-07-05,0.000,1246752000,1246838399 +2009-07-04,0.000,1246665600,1246751999 +2009-07-03,0.000,1246579200,1246665599 +2009-07-02,0.000,1246492800,1246579199 +2009-07-01,0.000,1246406400,1246492799 +2009-06-30,0.000,1246320000,1246406399 +2009-06-29,0.000,1246233600,1246319999 +2009-06-28,0.000,1246147200,1246233599 +2009-06-27,0.000,1246060800,1246147199 +2009-06-26,0.000,1245974400,1246060799 +2009-06-25,0.000,1245888000,1245974399 +2009-06-24,0.000,1245801600,1245887999 +2009-06-23,0.000,1245715200,1245801599 +2009-06-22,0.000,1245628800,1245715199 +2009-06-21,0.000,1245542400,1245628799 +2009-06-20,0.000,1245456000,1245542399 +2009-06-19,0.000,1245369600,1245455999 +2009-06-18,0.000,1245283200,1245369599 +2009-06-17,0.000,1245196800,1245283199 +2009-06-16,0.000,1245110400,1245196799 +2009-06-15,0.000,1245024000,1245110399 +2009-06-14,0.000,1244937600,1245023999 +2009-06-13,0.000,1244851200,1244937599 +2009-06-12,0.000,1244764800,1244851199 +2009-06-11,0.000,1244678400,1244764799 +2009-06-10,0.000,1244592000,1244678399 +2009-06-09,0.000,1244505600,1244591999 +2009-06-08,0.000,1244419200,1244505599 +2009-06-07,0.000,1244332800,1244419199 +2009-06-06,0.000,1244246400,1244332799 +2009-06-05,0.000,1244160000,1244246399 +2009-06-04,0.000,1244073600,1244159999 +2009-06-03,0.000,1243987200,1244073599 +2009-06-02,0.000,1243900800,1243987199 +2009-06-01,0.000,1243814400,1243900799 +2009-05-31,0.000,1243728000,1243814399 +2009-05-30,0.000,1243641600,1243727999 +2009-05-29,0.000,1243555200,1243641599 +2009-05-28,0.000,1243468800,1243555199 +2009-05-27,0.000,1243382400,1243468799 +2009-05-26,0.000,1243296000,1243382399 +2009-05-25,0.000,1243209600,1243295999 +2009-05-24,0.000,1243123200,1243209599 +2009-05-23,0.000,1243036800,1243123199 +2009-05-22,0.000,1242950400,1243036799 +2009-05-21,0.000,1242864000,1242950399 +2009-05-20,0.000,1242777600,1242863999 +2009-05-19,0.000,1242691200,1242777599 +2009-05-18,0.000,1242604800,1242691199 +2009-05-17,0.000,1242518400,1242604799 +2009-05-16,0.000,1242432000,1242518399 +2009-05-15,0.000,1242345600,1242431999 +2009-05-14,0.000,1242259200,1242345599 +2009-05-13,0.000,1242172800,1242259199 +2009-05-12,0.000,1242086400,1242172799 +2009-05-11,0.000,1242000000,1242086399 +2009-05-10,0.000,1241913600,1241999999 +2009-05-09,0.000,1241827200,1241913599 +2009-05-08,0.000,1241740800,1241827199 +2009-05-07,0.000,1241654400,1241740799 +2009-05-06,0.000,1241568000,1241654399 +2009-05-05,0.000,1241481600,1241567999 +2009-05-04,0.000,1241395200,1241481599 +2009-05-03,0.000,1241308800,1241395199 +2009-05-02,0.000,1241222400,1241308799 +2009-05-01,0.000,1241136000,1241222399 +2009-04-30,0.000,1241049600,1241135999 +2009-04-29,0.000,1240963200,1241049599 +2009-04-28,0.000,1240876800,1240963199 +2009-04-27,0.000,1240790400,1240876799 +2009-04-26,0.000,1240704000,1240790399 +2009-04-25,0.000,1240617600,1240703999 +2009-04-24,0.000,1240531200,1240617599 +2009-04-23,0.000,1240444800,1240531199 +2009-04-22,0.000,1240358400,1240444799 +2009-04-21,0.000,1240272000,1240358399 +2009-04-20,0.000,1240185600,1240271999 +2009-04-19,0.000,1240099200,1240185599 +2009-04-18,0.000,1240012800,1240099199 +2009-04-17,0.000,1239926400,1240012799 +2009-04-16,0.000,1239840000,1239926399 +2009-04-15,0.000,1239753600,1239839999 +2009-04-14,0.000,1239667200,1239753599 +2009-04-13,0.000,1239580800,1239667199 +2009-04-12,0.000,1239494400,1239580799 +2009-04-11,0.000,1239408000,1239494399 +2009-04-10,0.000,1239321600,1239407999 +2009-04-09,0.000,1239235200,1239321599 +2009-04-08,0.000,1239148800,1239235199 +2009-04-07,0.000,1239062400,1239148799 +2009-04-06,0.000,1238976000,1239062399 +2009-04-05,0.000,1238889600,1238975999 +2009-04-04,0.000,1238803200,1238889599 +2009-04-03,0.000,1238716800,1238803199 +2009-04-02,0.000,1238630400,1238716799 +2009-04-01,0.000,1238544000,1238630399 +2009-03-31,0.000,1238457600,1238543999 +2009-03-30,0.000,1238371200,1238457599 +2009-03-29,0.000,1238284800,1238371199 +2009-03-28,0.000,1238198400,1238284799 +2009-03-27,0.000,1238112000,1238198399 +2009-03-26,0.000,1238025600,1238111999 +2009-03-25,0.000,1237939200,1238025599 +2009-03-24,0.000,1237852800,1237939199 +2009-03-23,0.000,1237766400,1237852799 +2009-03-22,0.000,1237680000,1237766399 +2009-03-21,0.000,1237593600,1237679999 +2009-03-20,0.000,1237507200,1237593599 +2009-03-19,0.000,1237420800,1237507199 +2009-03-18,0.000,1237334400,1237420799 +2009-03-17,0.000,1237248000,1237334399 +2009-03-16,0.000,1237161600,1237247999 +2009-03-15,0.000,1237075200,1237161599 +2009-03-14,0.000,1236988800,1237075199 +2009-03-13,0.000,1236902400,1236988799 +2009-03-12,0.000,1236816000,1236902399 +2009-03-11,0.000,1236729600,1236815999 +2009-03-10,0.000,1236643200,1236729599 +2009-03-09,0.000,1236556800,1236643199 +2009-03-08,0.000,1236470400,1236556799 +2009-03-07,0.000,1236384000,1236470399 +2009-03-06,0.000,1236297600,1236383999 +2009-03-05,0.000,1236211200,1236297599 +2009-03-04,0.000,1236124800,1236211199 +2009-03-03,0.000,1236038400,1236124799 +2009-03-02,0.000,1235952000,1236038399 +2009-03-01,0.000,1235865600,1235951999 +2009-02-28,0.000,1235779200,1235865599 +2009-02-27,0.000,1235692800,1235779199 +2009-02-26,0.000,1235606400,1235692799 +2009-02-25,0.000,1235520000,1235606399 +2009-02-24,0.000,1235433600,1235519999 +2009-02-23,0.000,1235347200,1235433599 +2009-02-22,0.000,1235260800,1235347199 +2009-02-21,0.000,1235174400,1235260799 +2009-02-20,0.000,1235088000,1235174399 +2009-02-19,0.000,1235001600,1235087999 +2009-02-18,0.000,1234915200,1235001599 +2009-02-17,0.000,1234828800,1234915199 +2009-02-16,0.000,1234742400,1234828799 +2009-02-15,0.000,1234656000,1234742399 +2009-02-14,0.000,1234569600,1234655999 +2009-02-13,0.000,1234483200,1234569599 +2009-02-12,0.000,1234396800,1234483199 +2009-02-11,0.000,1234310400,1234396799 +2009-02-10,0.000,1234224000,1234310399 +2009-02-09,0.000,1234137600,1234223999 +2009-02-08,0.000,1234051200,1234137599 +2009-02-07,0.000,1233964800,1234051199 +2009-02-06,0.000,1233878400,1233964799 +2009-02-05,0.000,1233792000,1233878399 +2009-02-04,0.000,1233705600,1233791999 +2009-02-03,0.000,1233619200,1233705599 +2009-02-02,0.000,1233532800,1233619199 +2009-02-01,0.000,1233446400,1233532799 +2009-01-31,0.000,1233360000,1233446399 +2009-01-30,0.000,1233273600,1233359999 +2009-01-29,0.000,1233187200,1233273599 +2009-01-28,0.000,1233100800,1233187199 +2009-01-27,0.000,1233014400,1233100799 +2009-01-26,0.000,1232928000,1233014399 +2009-01-25,0.000,1232841600,1232927999 +2009-01-24,0.000,1232755200,1232841599 +2009-01-23,0.000,1232668800,1232755199 +2009-01-22,0.000,1232582400,1232668799 +2009-01-21,0.000,1232496000,1232582399 +2009-01-20,0.000,1232409600,1232495999 +2009-01-19,0.000,1232323200,1232409599 +2009-01-18,0.000,1232236800,1232323199 +2009-01-17,0.000,1232150400,1232236799 +2009-01-16,0.000,1232064000,1232150399 +2009-01-15,0.000,1231977600,1232063999 +2009-01-14,0.000,1231891200,1231977599 +2009-01-13,0.000,1231804800,1231891199 +2009-01-12,0.000,1231718400,1231804799 +2009-01-11,0.000,1231632000,1231718399 +2009-01-10,0.000,1231545600,1231631999 +2009-01-09,0.000,1231459200,1231545599 +2009-01-08,0.000,1231372800,1231459199 +2009-01-07,0.000,1231286400,1231372799 +2009-01-06,0.000,1231200000,1231286399 +2009-01-05,0.000,1231113600,1231199999 +2009-01-04,0.000,1231027200,1231113599 +2009-01-03,0.000,1230940800,1231027199 diff --git a/bitcoind/docker-compose.yaml b/bitcoind/docker-compose.yaml new file mode 100644 index 0000000..bf73e81 --- /dev/null +++ b/bitcoind/docker-compose.yaml @@ -0,0 +1,13 @@ +version: '3' +services: + bitcoind: + image: kylemanna/bitcoind + volumes: + - ./data-200k:/bitcoin/.bitcoin +# command: ["bitcoind", "-stopatheight=80000", "-printtoconsole"] + command: [ + "bitcoind", "-printtoconsole", "-rpcallowip=0.0.0.0/0", + "-rpcbind=0.0.0.0","-listen","-rpcuser=local","-rpcpassword=local", + "-connect=0", "-rest", "-txindex"] + ports: + - 8332:8332 diff --git a/bitcoingraph/__init__.py b/bitcoingraph/__init__.py index 033d87e..b052a1d 100644 --- a/bitcoingraph/__init__.py +++ b/bitcoingraph/__init__.py @@ -4,9 +4,13 @@ A Python library for exploring the Bitcoin transaction graph. """ - -from bitcoingraph.bitcoingraph import BitcoinGraph +import platform __author__ = 'Bernhard Haslhofer, Roman Karl' __license__ = "MIT" __version__ = '0.3.2dev' + +if platform.python_implementation() == "PyPy": + print("WARNING: You are running using pypy. Neo4j driver is not compatible with it, so " + "all neo4j related functions will fail. Pypy can only be used to speed up computes " + "that do not include neo4j, such as bcgraph-compute-entities") \ No newline at end of file diff --git a/bitcoingraph/address.py b/bitcoingraph/address.py new file mode 100644 index 0000000..711e184 --- /dev/null +++ b/bitcoingraph/address.py @@ -0,0 +1,123 @@ +import queue +import threading +from time import sleep +from typing import List, Dict, Set, Iterable + +import neo4j +import tqdm +from bitcoinlib.keys import Key + + +def fetch_addresses_by_block(session: neo4j.Session, start_height, max_height) -> List[str]: + """ + Returns all the addresses used in a given block + """ + query = """ + MATCH (b:Block) + WHERE b.height >= $lower AND b.height <= $higher + WITH b + MATCH (b)-[:CONTAINS]->(t)-[:OUTPUT]->(o)-[:USES]->(a) + WHERE a.address STARTS WITH "pk_" AND NOT EXISTS((a)-[:GENERATES]->()) + RETURN collect(distinct a.address) as addresses + """ + addresses = session.run(query, stream=True, lower=start_height, higher=max_height).single() + return addresses[0] if addresses else [] + + +def _fetch_address_by_block_thread(session: neo4j.Session, batch_size: int, start_height: int, max_height: int, + result_queue: queue.Queue, stop_queue: queue.Queue): + idx = start_height + try: + while stop_queue.empty() and idx < max_height: + data = fetch_addresses_by_block(session, idx, idx + batch_size) + result_queue.put(data) + idx += batch_size + + except Exception as e: + print(f"Thread failed: {e}") + finally: + result_queue.put(None) + session.close() + + +def get_p2pkh(k: Key): + return k.address() + + +def get_p2wpkh(k: Key): + return k.address(compressed=True, encoding="bech32") + + +def generate_from_address_list(addresses: Iterable[str], pk_to_addresses: Dict[str, List[str]]): + for addr in addresses: + if addr.endswith("CHECKSIG"): + pk = addr[3:-12] + else: + pk = addr[3:] + + try: + pk_key = Key(pk) + except Exception: + continue + + pk_to_addresses[addr] = [get_p2pkh(pk_key), get_p2wpkh(pk_key)] + + +def save_generated_addresses(session: neo4j.Session, pk_to_addresses: Dict[str, List[str]], batch_size=2000): + query = """ + UNWIND $pk_map AS addresses + WITH addresses[0] as pk, tail(addresses) as list_generated + MATCH (a:Address {address: pk}) + WITH a, list_generated + UNWIND list_generated as generated + MERGE (b:Address {address: generated}) + WITH a,b + MERGE (a)-[:GENERATES]->(b) + """ + data = [[pk, addrs[0], addrs[1]] for pk, addrs in pk_to_addresses.items()] + for i in range(0, len(data), batch_size): + session.run(query, pk_map=data[i:i + batch_size]) + + +def process_create_pk_to_generated(batch_size: int, start_height: int, max_height: int, driver: neo4j.Driver): + result_queue = queue.Queue() + stop_queue = queue.Queue() + thread_session = driver.session() + + if max_height is None: + max_height = thread_session.run("MATCH (b:Block) RETURN max(b.height) as maxHeight").data()[0]["maxHeight"] + + print(f"Running with {start_height} <= height < {max_height}") + + thread = threading.Thread(target=_fetch_address_by_block_thread, + args=(thread_session, batch_size, start_height, max_height, result_queue, stop_queue,)) + thread.start() + + pk_to_addresses = {} + progress_bar = tqdm.tqdm(total=max_height - start_height) + while True: + try: + addresses = result_queue.get_nowait() + if addresses is None: + break + + generate_from_address_list(addresses, pk_to_addresses) + + progress_bar.update(batch_size) + except queue.Empty: + sleep(0.5) + + except KeyboardInterrupt: + pass + + progress_bar.set_description(f"Finished processing {len(pk_to_addresses)} addresses, saving results") + + with driver.session() as session: + save_generated_addresses(session, pk_to_addresses) + + +def upsert_generated_addresses(session: neo4j.Session, pk_addresses: Set[str]): + pk_to_addresses = {} + generate_from_address_list(pk_addresses, pk_to_addresses) + save_generated_addresses(session, pk_to_addresses) + return pk_to_addresses diff --git a/bitcoingraph/bitcoind.py b/bitcoingraph/bitcoind.py index 1ebc963..539dedd 100755 --- a/bitcoingraph/bitcoind.py +++ b/bitcoingraph/bitcoind.py @@ -2,14 +2,21 @@ Bitcoin Core JSON-RPC interface. """ +import gzip import logging +import os +from typing import Optional + +try: + import paramiko +except ImportError: + pass import requests import json import time - __author__ = 'Bernhard Haslhofer (bernhard.haslhofer@ait.ac.at)' __copyright__ = 'Copyright 2015, Bernhard Haslhofer' __license__ = "MIT" @@ -22,6 +29,22 @@ class BitcoindException(Exception): pass +class SSHTunnel: + def __init__(self, client: 'paramiko.SSHClient'): + self.client = client + + @classmethod + def from_config_file(cls, path): + with open(path, 'r') as file: + vars = {"port": 22, **json.load(file)} + + print("Using SSH tunnel with at {}:{}".format(vars["hostname"], vars["port"])) + ssh_client = paramiko.SSHClient() + ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + ssh_client.connect(**vars) + return cls(ssh_client) + + class JSONRPCInterface: """ A generic JSON-RPC interface with keep-alive session reuse. @@ -100,15 +123,24 @@ def _execute(self, request): class RESTInterface: - def __init__(self, url): + def __init__(self, url, ssh_tunnel: Optional[SSHTunnel] = None, timeout: Optional[int] = None): self._session = requests.Session() self._url = url + self._ssh_tunnel = ssh_tunnel + self._timeout = timeout def get_block(self, hash): - r = self._session.get(self._url + 'block/{}.json'.format(hash)) - if r.status_code != 200: - raise Exception('REST request was not successful') - return r.json() + if self._ssh_tunnel: + curl_command = """curl http://127.0.0.1:8332/rest/block/{}.json""".format(hash) + stdin, stdout, stderr = self._ssh_tunnel.client.exec_command(curl_command) + output = stdout.read().decode('utf-8') + json_output = json.loads(output) + return json_output + else: + r = self._session.get(self._url + 'block/{}.json'.format(hash)) + if r.status_code != 200: + raise Exception('REST request was not successful') + return r.json() class BitcoinProxy: @@ -119,7 +151,8 @@ class BitcoinProxy: `here `_ """ - def __init__(self, host, port, rpc_user=None, rpc_pass=None, method='RPC'): + def __init__(self, host, port, rpc_user=None, rpc_pass=None, method='RPC', ssh_tunnel=None, cache_path=None, + timeout=None): """ Creates a Bitcoin JSON RPC Service object. @@ -128,13 +161,31 @@ def __init__(self, host, port, rpc_user=None, rpc_pass=None, method='RPC'): :rtype: BitcoinProxy """ self.method = method - rest_url = 'http://{}:{}/rest/'.format(host, port) rpc_url = 'http://{}:{}@{}:{}/'.format(rpc_user, rpc_pass, host, port) - print(f'REST URL is: {rest_url}') print(f'RPC URL is: {rpc_url}') self._jsonrpc_proxy = JSONRPCInterface(rpc_url) + if method == 'REST': - self._rest_proxy = RESTInterface(rest_url) + rest_url = 'http://{}:{}/rest/'.format(host, port) + print(f'REST URL is: {rest_url}') + self._rest_proxy = RESTInterface(rest_url, ssh_tunnel=ssh_tunnel, timeout=timeout) + + self._cache_path = cache_path + + def _block_cache_path(self, block_hash: str) -> str: + return "{}/{}.json.gz".format(self._cache_path, block_hash) + + def _get_from_cache(self, block_hash: str): + path = self._block_cache_path(block_hash) + if os.path.exists(path): + with gzip.open(path, 'rb') as f: + return json.load(f) + + return None + + def _write_to_cache(self, r, block_hash: str): + with gzip.open(self._block_cache_path(block_hash), "wt+") as f: + json.dump(r, f) def getblock(self, block_hash): """ @@ -144,10 +195,20 @@ def getblock(self, block_hash): :return: block as JSON :rtype: str """ + if self._cache_path: + try: + return self._get_from_cache(block_hash) + except Exception as e: + print(f"Failed to parse json {self._block_cache_path(block_hash)}, getting new") + if self.method == 'REST': r = self._rest_proxy.get_block(block_hash) + if self._cache_path: + self._write_to_cache(r, block_hash) else: - r = self._jsonrpc_proxy.call('getblock', block_hash) + r = self._jsonrpc_proxy.call('getblock', block_hash, 3) + if self._cache_path: + self._write_to_cache(r, block_hash) return r def getblockcount(self): diff --git a/bitcoingraph/bitcoingraph.py b/bitcoingraph/bitcoingraph.py index 380c1d9..6af78e6 100644 --- a/bitcoingraph/bitcoingraph.py +++ b/bitcoingraph/bitcoingraph.py @@ -5,8 +5,14 @@ the Bitcoin block chain. """ +import os +import shutil +import subprocess +from pathlib import Path -import logging +from bitcoingraph.logger import get_logger + +import tqdm from bitcoingraph.bitcoind import BitcoinProxy, BitcoindException from bitcoingraph.blockchain import Blockchain @@ -15,7 +21,7 @@ from bitcoingraph.helper import sort from bitcoingraph.writer import CSVDumpWriter -logger = logging.getLogger('bitcoingraph') +logger = get_logger('bitcoingraph') class BitcoingraphException(Exception): @@ -37,11 +43,18 @@ class BitcoinGraph: def __init__(self, **config): """Create an instance based on the configuration.""" - self.blockchain = self.__get_blockchain(config['blockchain']) + self._blockchain = None + self.blockchain_config = config['blockchain'] if 'neo4j' in config: nc = config['neo4j'] self.graph_db = GraphController(nc['host'], nc['port'], nc['user'], nc['pass']) + @property + def blockchain(self): + if self._blockchain is None: + self._blockchain = self.__get_blockchain(self.blockchain_config) + return self._blockchain + @staticmethod def __get_blockchain(config): """Connect to Bitcoin Core (via JSON-RPC) and return a @@ -115,7 +128,7 @@ def get_entity(self, id): def get_path(self, start, end): """Return a path between addresses.""" - return self.graph_db.get_path(start, end) + raise NotImplemented("This function was removed in new version") def get_received_bitcoins(self, address): """Return the total number of bitcoins received by this address.""" @@ -125,54 +138,137 @@ def get_unspent_bitcoins(self, address): """Return the current balance of this address.""" return self.graph_db.get_unspent_bitcoins(address) - def export(self, start, end, output_path=None, plain_header=False, separate_header=True, - progress=None, deduplicate_transactions=True): - """Export the blockchain into CSV files.""" - if output_path is None: - output_path = 'blocks_{}_{}'.format(start, end) + @staticmethod + def append_csv(output_path: Path, updates_path: Path): + print("Appending new CSVs to previous") + for base_name in ['addresses.csv', 'blocks.csv', 'outputs.csv', 'transactions.csv', 'rel_block_block.csv.csv', + 'rel_block_tx.csv.csv', 'rel_input.csv', 'rel_output_address.csv', 'rel_tx_output.csv']: + receiving_path = output_path.joinpath(base_name) + sending_path = updates_path.joinpath(base_name) + subprocess.run(f"cat {str(sending_path.expanduser().resolve().absolute())} >> {str(receiving_path.expanduser().resolve().absolute())}", shell=True) - number_of_blocks = end - start + 1 - with CSVDumpWriter(output_path, plain_header, separate_header) as writer: - for block in self.blockchain.get_blocks_in_range(start, end): - writer.write(block) - if progress: - processed_blocks = block.height - start + 1 - last_percentage = ((processed_blocks - 1) * 100) // number_of_blocks - percentage = (processed_blocks * 100) // number_of_blocks - if percentage > last_percentage: - progress(processed_blocks / number_of_blocks) - if separate_header: - sort(output_path, 'addresses.csv', '-u') - if deduplicate_transactions: - for base_name in ['transactions', 'rel_tx_output', - 'outputs', 'rel_output_address']: - sort(output_path, base_name + '.csv', '-u') - - def synchronize(self, max_blocks=None): + @staticmethod + def sort(output_path): + print("\nWriting blocks finished. Running sorts. This will take a long time.") + for base_name in ['addresses', 'transactions', 'rel_tx_output', 'outputs', 'rel_output_address']: + print(f"Sorting {base_name}.csv") + sort(output_path, base_name + '.csv', '-u') + + def resume_export(self, end, output_path, progress=None, resume=False): + assert output_path is not None, "When using resume, output path must be provided." + + # Get latest block exported + output_path = Path(output_path) + assert output_path.joinpath("blocks.csv").exists(), "When using resume, the blocks.csv must exist" + with open(output_path.joinpath("blocks.csv")) as f: + for line in f.readlines(): + pass + start = int(line.split(",")[1]) + 1 + + # setup outpath as {outpath}/resume + assert output_path.exists(), "When using resume, output path must exist." + base_path = Path(output_path) + + output_path = output_path.joinpath("resume") + if output_path.exists(): + shutil.rmtree(str(output_path.resolve().absolute())) + output_path.mkdir(exist_ok=True) + + # actually start resume + try: + number_of_blocks = end - start + 1 + with CSVDumpWriter(output_path) as writer: + for block in tqdm.tqdm(self.blockchain.get_blocks_in_range(start, end), total=end - start): + writer.write(block) + if progress: + processed_blocks = block.height - start + 1 + last_percentage = ((processed_blocks - 1) * 100) // number_of_blocks + percentage = (processed_blocks * 100) // number_of_blocks + if percentage > last_percentage: + progress(processed_blocks / number_of_blocks) + except KeyboardInterrupt as e: + answer = input("Save progress? [y/n]").strip().lower() + if answer != "y": + print("Exited without saving") + raise e + + # merge files together + self.append_csv(base_path, output_path) + + # sort them again + self.sort(base_path) + + def export(self, start, end, output_path=None, progress=None, sort_only=False, resume=False): + """Export the blockchain into CSV files.""" + if resume: + self.resume_export(end, output_path, progress) + return + + if not sort_only: + if output_path is None: + output_path = 'blocks_{}_{}'.format(start, end) + + number_of_blocks = end - start + 1 + with CSVDumpWriter(output_path) as writer: + for block in tqdm.tqdm(self.blockchain.get_blocks_in_range(start, end), total=end - start): + writer.write(block) + if progress: + processed_blocks = block.height - start + 1 + last_percentage = ((processed_blocks - 1) * 100) // number_of_blocks + percentage = (processed_blocks * 100) // number_of_blocks + if percentage > last_percentage: + progress(processed_blocks / number_of_blocks) + + self.sort(output_path) + + def synchronize(self, max_height=None, lag=0): """Synchronise the graph database with the blockchain information from the bitcoin client. """ - start = self.graph_db.get_max_block_height() + 1 - blockchain_end = self.blockchain.get_max_block_height() - 2 + max_block_height = self.graph_db.get_max_block_height() + if max_block_height is None: + start = 0 + else: + start = self.graph_db.get_max_block_height() + 1 + blockchain_end = self.blockchain.get_max_block_height() - lag if start > blockchain_end: - print('Already up-to-date.') + return else: - if max_blocks is None: + if max_height is None: end = blockchain_end else: - end = min(start + max_blocks - 1, blockchain_end) - print('add blocks', start, 'to', end) + end = min(max_height, blockchain_end) + if start >= end: + logger.warn(f"Start ({start}) >= end ({end}). Exiting.") + raise StopIteration + + logger.info(f"Getting blocks in range {start}-{end}") for block in self.blockchain.get_blocks_in_range(start, end): + if block.height >= self.blockchain.get_max_block_height() - lag: + return + logger.info("Adding block") self.graph_db.add_block(block) + yield block.height + if block.height >= max_height: + logger.info("Reached max height. Exiting") + raise StopIteration -def compute_entities(input_path, sort_input=False): - """Read exported CSV files containing blockchain information and +def compute_entities(input_path, sort_input=True, sort_output_address=False): + """ + Read exported CSV files containing blockchain information and export entities into CSV files. """ - if sort_input: + if sort_output_address: + print("Sorting rel_output_address.csv") sort(input_path, 'rel_output_address.csv') - sort(input_path, 'rel_input.csv', '-k 2 -t ,') - entities.calculate_input_addresses(input_path) - sort(input_path, 'input_addresses.csv') + + if sort_input: + print("Sorting rel_input.csv") + sort(input_path, 'rel_input.csv', '-k 2 -t ,') + entities.calculate_input_addresses(input_path) + print("Sorting input_addresses.csv") + sort(input_path, 'input_addresses.csv') + + print("Computing entities") entities.compute_entities(input_path) diff --git a/bitcoingraph/blockchain.py b/bitcoingraph/blockchain.py index 2363a81..72eb632 100755 --- a/bitcoingraph/blockchain.py +++ b/bitcoingraph/blockchain.py @@ -4,7 +4,12 @@ An API for traversing the Bitcoin blockchain """ +import json +import os +import time +from typing import Iterator +from bitcoingraph.logger import get_logger from bitcoingraph.model import Block, Transaction from bitcoingraph.bitcoind import BitcoindException @@ -12,7 +17,7 @@ __copyright__ = 'Copyright 2015, Bernhard Haslhofer' __license__ = "MIT" - +logger = get_logger("blockchain") class BlockchainException(Exception): """ Exception raised when accessing or navigating the block chain. @@ -53,8 +58,20 @@ def get_block_by_hash(self, block_hash): """ # Returns block by hash try: + logger.info(f"Getting block: {block_hash}") + start = time.time() raw_block_data = self._bitcoin_proxy.getblock(block_hash) - return Block(self, json_data=raw_block_data) + interval = time.time()-start + logger.info(f"Took {interval} seconds to get block") + + if os.environ.get("BC_CACHE") == "1": + logger.info("Saving block in local cache") + with open(f"block-{block_hash}.json", "w+") as f: + f.write(json.dumps(raw_block_data)) + + logger.info("Parsing block") + block = Block.model_validate(raw_block_data) + return block except BitcoindException as exc: raise BlockchainException('Cannot retrieve block {}'.format(block_hash), exc) @@ -75,7 +92,7 @@ def get_block_by_height(self, block_height): raise BlockchainException( 'Cannot retrieve block with height {}'.format(block_height), exc) - def get_blocks_in_range(self, start_height=0, end_height=0): + def get_blocks_in_range(self, start_height=0, end_height=0) -> Iterator[Block]: """ Generates blocks in a given range. @@ -88,7 +105,7 @@ def get_blocks_in_range(self, start_height=0, end_height=0): while block.height <= end_height: yield block if block.has_next_block(): - block = block.next_block + block = self.get_block_by_hash(block.next_block_hash) else: break @@ -104,25 +121,9 @@ def get_transaction(self, tx_id): raw_tx_data = self._bitcoin_proxy.getrawtransaction(tx_id) return Transaction(self, json_data=raw_tx_data) except BitcoindException as exc: + print(exc) raise BlockchainException('Cannot retrieve transaction with id {}'.format(tx_id), exc) - def get_transactions(self, tx_ids): - """ - Returns transactions for given transaction ids. - - :param tx_ids: list of transaction ids - :return: list of transaction objects - :rtype: Transaction list - """ - try: - txs = [] - raw_txs_data = self._bitcoin_proxy.getrawtransactions(tx_ids) - for raw_tx_data in raw_txs_data: - txs.append(Transaction(raw_tx_data, self)) - return txs - except BitcoindException as exc: - raise BlockchainException('Cannot retrieve transactions {}'.format(tx_ids), exc) - def get_max_block_height(self): """ Returns maximum known block height. diff --git a/bitcoingraph/common.py b/bitcoingraph/common.py new file mode 100644 index 0000000..953cdc3 --- /dev/null +++ b/bitcoingraph/common.py @@ -0,0 +1,7 @@ +import platform + + +def is_pypy(): + if platform.python_implementation() == "PyPy": + return True + return False \ No newline at end of file diff --git a/bitcoingraph/entities.py b/bitcoingraph/entities.py index 6b8f165..289a4fe 100644 --- a/bitcoingraph/entities.py +++ b/bitcoingraph/entities.py @@ -1,10 +1,23 @@ import bisect +import copy import csv import os +import pickle +import queue +import random +import uuid +from pathlib import Path +from time import sleep +from typing import Dict, List, Set, Optional, Iterable, Sized +import neo4j +import tqdm -class Address: +from bitcoingraph.logger import get_logger + +logger = get_logger("entities") +class Address: counter = 0 def __init__(self, address, assign_number=False): @@ -149,3 +162,270 @@ def calculate_input_addresses(input_path): if match_address is not None: input_address_writer.writerow([txid, match_address]) + + +def get_addresses_grouped_by_transaction(session: 'neo4j.Session', start_height: int, max_height: int): + query = """ + MATCH (b:Block) + WHERE b.height >= $lower AND b.height <= $higher + WITH b + MATCH (b)-[:CONTAINS]->(t)<-[:INPUT]-(o)-[:USES]->(a) + WITH t, collect(distinct a.address) as addresses + OPTIONAL MATCH (a)-[:GENERATES]->(b:Address) + WHERE a.address in addresses AND not b.address in addresses + WITH t, addresses, collect(distinct b.address) as generatedOut + OPTIONAL MATCH (a)<-[:GENERATES]-(b:Address) + WHERE a.address in addresses AND not b.address in addresses + WITH t, addresses, generatedOut, collect(distinct b.address) as generatedIn + WITH t, addresses, generatedOut + generatedIn as generated + RETURN t.txid, addresses, generated + """ + result = session.run(query, stream=True, lower=start_height, higher=max_height) + return result.data() + + +def _fetch_outputs_thread(session: 'neo4j.Session', batch_size: int, skip: int, + result_queue: queue.Queue, stop_queue: queue.Queue): + + try: + query = """ + MATCH (t:Transaction)<-[:INPUT]-(:Output)-[:USES]->(a:Address) + WITH t,a + SKIP $skip + CALL { + WITH t,a + RETURN elementId(t) as elmId, collect(distinct elementId(a)) as addresses + } IN TRANSACTIONS + RETURN addresses + """ + cursor = session.run(query, stream=True, skip=skip) + + while True: + result = cursor.fetch(batch_size) + if not result: + break + if not stop_queue.empty(): + raise Exception("Received stop signal") + result_queue.put([{"addresses": g.get("addresses")} for g in result]) + + result_queue.put(None) + + except Exception as e: + print(f"Thread failed: {e}") + result_queue.put(-1) + finally: + print("exiting") + result_queue.put(None) + session.close() + + +class EntityGrouping: + def __init__(self): + self.entity_idx_counter = 0 + self.entity_idx_to_addresses: Dict[int, Set[str]] = {} + self.address_to_entity_idx: Dict[str, int] = {} + self.entity_idx_counter = 0 + self.counter_entities = 0 + self.counter_joined_entities = 0 + self.last_updated: Dict[int, int] = dict([]) + self.last_empty = 0 + + # @profile + def update_from_address_group(self, addresses: List[str]): + if len(addresses) <= 1: + return + + found_entities_idx: Set[int] = set([]) + + for addr in addresses: + entity_idx = self.address_to_entity_idx.get(addr, None) + if entity_idx is not None: + found_entities_idx.add(entity_idx) + + if found_entities_idx: + # Here we need to join all the addresses from the different entities together + min_entity_idx: int = min(found_entities_idx) + entity_address_set = self.entity_idx_to_addresses[min_entity_idx] + moved_addresses = set(addresses) + for entity_idx in found_entities_idx: + if entity_idx == min_entity_idx: + continue + + entity_addresses_to_merge = self.entity_idx_to_addresses.pop(entity_idx) + + moved_addresses.update(entity_addresses_to_merge) + entity_address_set.update(entity_addresses_to_merge) + + for addr in moved_addresses: + self.address_to_entity_idx[addr] = min_entity_idx + + self.entity_idx_to_addresses[min_entity_idx].update(moved_addresses) + self.counter_entities -= (len(found_entities_idx) - 1) + self.counter_joined_entities += len(found_entities_idx) - 1 + + else: + # create a new entity + entity_idx = self.entity_idx_counter + for addr in addresses: + self.address_to_entity_idx[addr] = entity_idx + self.entity_idx_to_addresses[entity_idx] = set(addresses) + + self.entity_idx_counter += 1 + self.counter_entities += 1 + + def save_entities(self, session: 'neo4j.Session'): + iterator = self.entity_idx_to_addresses.items() + for entity_idx, addresses in tqdm.tqdm(iterator, desc="Adding entities"): + if len(addresses) <= 1: + continue + addresses = list(addresses) + + result = session.run(""" + UNWIND $addresses as address + MATCH (a:Address {address: address}) + WITH a + OPTIONAL MATCH (a)<-[:OWNER_OF]-(e:Entity) + OPTIONAL MATCH (e)-[rel:OWNER_OF]->() + return e.entity_id as eid, e.name as name, count(rel) as count_rel + """, addresses=addresses).data() + + entities = [x['eid'] for x in result if x['eid'] is not None] + entity_names = [x['name'] for x in result if x['name'] is not None] + count_relationships = [x['count_rel'] for x in result if x['count_rel'] > 0] + entity_name = "+".join(entity_names) if entity_names else None + + if len(entities) == 0: + addresses.sort() + session.run(""" + CREATE (e:Entity {entity_id: $entity_id}) + WITH e + UNWIND $addresses as address + MATCH (a:Address {address: address}) + MERGE (a)<-[:OWNER_OF]-(e) + """, entity_id=addresses[0], addresses=addresses) + elif len(entities) == 1: + query = """ + UNWIND $addresses AS address + MATCH (a:Address {address: address}) + WITH a + MATCH (e:Entity {entity_id: $entity_id}) + MERGE (e)-[:OWNER_OF]->(a) + """ + session.run(query, entity_id=entities[0], addresses=addresses) + else: + # sort entities by number of relationships + entities = [x for _, x in sorted(zip(count_relationships, entities), reverse=True)] + set_entity_name = f"SET e.name = $entity_name" if entity_name else '' + query = """ + UNWIND $small_entities as sme_id + MATCH (e:Entity {entity_id: sme_id})-[:OWNER_OF]->(a) + CALL { + WITH e + DETACH DELETE e + } + WITH a + UNWIND $addresses as address + MATCH (all_a: Address {address: address}) + WITH distinct collect(a)+collect(all_a) as all_addresses + UNWIND all_addresses as a + MATCH (e:Entity {entity_id: $large_entity}) + CREATE (a)<-[:OWNER_OF]-(e) + %s + """ % set_entity_name + + session.run(query, small_entities=entities[1:], large_entity=entities[0], entity_name=entity_name, addresses=addresses) + + +def add_entities(batch_size: int, resume: str, driver: 'neo4j.Driver'): + session = driver.session() + result_queue = queue.Queue() + stop_queue = queue.Queue() + + if resume is not None: + path = Path(resume).resolve() + with open(path, "rb+") as f: + data = pickle.load(f) + current_transaction = data["iteration"] + entity_grouping = data["grouping"] + print(f"Resuming from {path} at transaction {current_transaction}") + else: + entity_grouping = EntityGrouping() + current_transaction = 0 + + # 2.69 is the average number of inputs per transactions. The real query would actually be + # RETURN count(distinct t), however this takes a lot of time, hence the use of estimate + count_transactions = session.run("MATCH (t:Transaction)<-[:INPUT]-() RETURN count(t) as ct").data()[0]["ct"] / 2.69 + count_transactions = int(round(count_transactions)) + + # This is the thread that continuously queries for the next batch_size transactions + # thread = threading.Thread(target=_fetch_outputs_thread, + # args=(session, batch_size, current_transaction, result_queue, stop_queue,)) + # thread.start() + + dump_path = f"./state_dump_{uuid.uuid4()}.pickle" + print(f"Dump file: {dump_path}") + try: + loop_counter = 0 + progress_bar = tqdm.tqdm(desc="Transactions read", total=count_transactions-current_transaction) + + query = """ + MATCH (t:Transaction)<-[:INPUT]-(:Output)-[:USES]->(a:Address) + WITH t,a + SKIP $skip + CALL { + WITH t,a + RETURN elementId(t) as elmId, collect(distinct a.address) as addresses + } IN TRANSACTIONS + RETURN addresses + """ + cursor = session.run(query, stream=True, skip=current_transaction) + + while True: + result = cursor.fetch(batch_size) + if not result: + break + + result_list = [{"addresses": g.get("addresses")} for g in result] + for result in result_list: + addresses = result["addresses"] + entity_grouping.update_from_address_group(addresses) + + batch_transaction = len(result_list) + current_transaction += batch_transaction + progress_bar.update(batch_transaction) + + loop_counter += 1 + progress_bar.set_postfix({'Total entities': len(entity_grouping.entity_idx_to_addresses), + 'Counter joined': entity_grouping.counter_joined_entities}) + + if loop_counter % int(round(50000 / batch_size)) == 0: + with open(dump_path, "wb+") as f: + print("Dumping current state") + pickle.dump({"iteration": current_transaction, "grouping": entity_grouping}, f) + + except KeyboardInterrupt: + # stop_queue.put("Time to stop") + # for i in range(10): + # if thread.is_alive(): + # sleep(2) + pass + + with driver.session() as session: + sleep(1) + entity_grouping.save_entities(session) + + +def upsert_entities(session: neo4j.Session, addresses_per_transaction: List[Set[str]], pk_to_addresses: Dict[str, List[str]]): + entity_grouping = EntityGrouping() + + logger.info("- Computing") + for k, v in pk_to_addresses.items(): + addresses = set(v) + addresses.add(k) + entity_grouping.update_from_address_group(list(addresses)) + + for addresses in addresses_per_transaction: + entity_grouping.update_from_address_group(list(addresses)) + + logger.info("- Preparing queries") + entity_grouping.save_entities(session) diff --git a/bitcoingraph/graphdb.py b/bitcoingraph/graphdb.py index e7e0fa1..1c86789 100644 --- a/bitcoingraph/graphdb.py +++ b/bitcoingraph/graphdb.py @@ -1,7 +1,16 @@ +from bitcoingraph.address import upsert_generated_addresses +from bitcoingraph.blockchain import BlockchainException +from bitcoingraph.common import is_pypy +from bitcoingraph.entities import upsert_entities +from bitcoingraph.logger import get_logger + +if not is_pypy(): + import neo4j from bitcoingraph.neo4j import Neo4jController -from bitcoingraph.helper import to_time, to_json +from bitcoingraph.helper import to_time +logger = get_logger("graphdb") def round_value(bitcoin_value): return round(bitcoin_value, 8) @@ -12,7 +21,11 @@ class GraphController: rows_per_page_default = 20 def __init__(self, host, port, user, password): - self.graph_db = Neo4jController(host, port, user, password) + self.driver = neo4j.GraphDatabase.driver(f"bolt://{host}:{port}", + auth=(user, password), + connection_timeout=3600) + + self.graph_db = Neo4jController(self.driver) def get_address_info(self, address, date_from=None, date_to=None, rows_per_page=rows_per_page_default): @@ -79,29 +92,114 @@ def add_identity(self, address, name, link, source): def delete_identity(self, id): self.graph_db.identity_delete_query(id) - def get_path(self, address1, address2): - return Path(self.graph_db.path_query(address1, address2)) - def get_max_block_height(self): return self.graph_db.get_max_block_height() def add_block(self, block): - print('add block', block.height) + block_query = """ + CREATE (b:Block {hash: $hash, height: $height, timestamp: $timestamp}) + WITH b + OPTIONAL MATCH (bprev:Block {height: $height-1}) + CALL { + WITH b,bprev + WITH b, bprev WHERE bprev is not null + CREATE (b)-[:APPENDS]->(bprev) + } + """ + + transaction_query = """ + UNWIND $transactions as tx + MATCH (b:Block {height: $height}) + CREATE (b)-[:CONTAINS]->(t:Transaction {txid: tx.txid, coinbase: tx.coinbase}) + """ + + input_query = """ + UNWIND $inputs as input + MATCH (o:Output {txid_n: input.txid_n}) + MATCH (t:Transaction {txid: input.txid}) + CREATE (o)-[:INPUT]->(t) + """ + + output_query = """ + UNWIND $outputs as output + CREATE (o:Output {n: output.n, txid_n: output.txid_n, type: output.type, value: output.value}) + WITH o, output + MATCH (t:Transaction {txid: output.txid}) + CREATE (t)-[:OUTPUT]->(o) + """ + + address_query = """ + UNWIND $addresses as address + MERGE (a:Address {address: address.address}) + WITH a, address + MATCH (o:Output {txid_n: address.txid_n}) + CREATE (o)-[:USES]->(a) + """ + with self.graph_db.transaction() as db_transaction: - block_node_id = db_transaction.add_block(block) - for index, tx in enumerate(block.transactions): - print('add transaction {} of {} (txid: {})'.format( - index + 1, len(block.transactions), tx.txid)) - tx_node_id = db_transaction.add_transaction(block_node_id, tx) - if not tx.is_coinbase(): - for input in tx.inputs: - db_transaction.add_input(tx_node_id, input.output_reference) - for output in tx.outputs: - output_node_id = db_transaction.add_output(tx_node_id, output) - for address in output.addresses: - db_transaction.add_address(output_node_id, address) - print('create entities for block (node id: {})'.format(block_node_id)) - self.graph_db.create_entities(block_node_id) + # block_node_id = db_transaction.add_block(block) + transactions = [] + inputs = [] + outputs = [] + addresses = [] + try: + pk_addresses = set([]) + grouped_addresses_per_tx = [] + + logger.info("Preparing DB transaction queries") + for index, tx in enumerate(block.transactions): + # tx_node_id = db_transaction.add_transaction(block_node_id, tx) + transactions.append({'txid': tx.txid, 'coinbase': tx.is_coinbase()}) + grouped_addresses_per_tx.append(set()) + if not tx.is_coinbase(): + for input_ in tx.inputs: + inputs.append({ + 'txid_n': '{}_{}'.format(input_.output_reference.txid, input_.output_reference.index), + 'txid': tx.txid + }) + + # db_transaction.add_input(tx_node_id, input.output_reference) + grouped_addresses_per_tx[index].update(input_.output_reference.addresses) + + for output in tx.outputs: + output_txid_n = '{}_{}'.format(output.txid, output.index) + outputs.append({ + 'txid_n': output_txid_n, 'n': output.index, 'value': output.value, 'type': output.type, + 'txid': output.txid + }) + # output_node_id = db_transaction.add_output(tx_node_id, output) + for address in output.addresses: + addresses.append({ + "address": address, "txid_n": output_txid_n + }) + # db_transaction.add_address(output_node_id, address) + if address.startswith("pk_"): + pk_addresses.add(address) + + logger.debug("Transaction: block") + db_transaction.tx.run( + block_query, {'hash': block.hash, 'height': block.height, 'timestamp': block.timestamp} + ) + logger.debug("Transaction: transactions") + db_transaction.tx.run(transaction_query, transactions=transactions, height=block.height) + logger.debug("Transaction: outputs") + db_transaction.tx.run(output_query, outputs=outputs) + logger.debug("Transaction: inputs") + db_transaction.tx.run(input_query, inputs=inputs) + logger.debug("Transaction: addresses") + db_transaction.tx.run(address_query, addresses=addresses) + + logger.info("Creating generated addresses transactions") + pk_to_addresses = upsert_generated_addresses(db_transaction.tx, pk_addresses) + logger.info("Starting entities computations") + upsert_entities(db_transaction.tx, grouped_addresses_per_tx, pk_to_addresses) + logger.info("Block completed. Saving transactions to database, this may take a few minutes.") + + except BlockchainException as e: + if e.inner_exc and e.inner_exc.args and 'genesis' in e.inner_exc.args[0]: + logger.warn("Skipping inputs for genesis block") + else: + raise e class Address: diff --git a/bitcoingraph/helper.py b/bitcoingraph/helper.py index b76763e..dc05688 100644 --- a/bitcoingraph/helper.py +++ b/bitcoingraph/helper.py @@ -2,8 +2,10 @@ import datetime import json import os +import shutil import subprocess import sys +from pathlib import Path def to_time(numeric_string, as_date=False): @@ -30,11 +32,26 @@ def to_json(raw_data): indent=4, separators=(',', ': ')) -def sort(path, filename, args=''): - if sys.platform == 'darwin': - s = 'LC_ALL=C gsort -S 50% --parallel=4 {0} {1} -o {1}' +def sort(output_directory, filename, args=''): + output_directory = Path(output_directory).resolve() + tmp_directory = output_directory.joinpath('tmp') + + if os.path.exists(tmp_directory): + shutil.rmtree(tmp_directory) + os.mkdir(tmp_directory) + + cpus = os.cpu_count() + # I'm not sure why this if/else was used in the first place, since the second + # command works on Mac and the first doesn't. Leaving it for the moment + # if sys.platform == 'darwin': + # s = 'LC_ALL=C gsort -T {tmp_path} -S 50% --parallel=' + str(cpus) + ' {args} {input_filename} -o {filename}' + # else: + s = 'LC_ALL=C sort -T {tmp_path} -S 50% --parallel=' + str(cpus) + ' {args} {input_filename} -o {filename}' + + cmd = s.format(tmp_path=tmp_directory.absolute(), args=args, input_filename=output_directory.joinpath(filename), filename=output_directory.joinpath(filename+".sorted")) + print(f"Running: \n{cmd}") + status = subprocess.call(cmd, shell=True) + if status == 0: + os.replace(output_directory.joinpath(filename+".sorted"), output_directory.joinpath(filename)) else: - s = 'LC_ALL=C sort -S 50% --parallel=4 {0} {1} -o {1}' - status = subprocess.call(s.format(args, os.path.join(path, filename)), shell=True) - if status != 0: raise Exception('unable to sort file: {}'.format(filename)) diff --git a/bitcoingraph/logger.py b/bitcoingraph/logger.py new file mode 100644 index 0000000..7e4a1dc --- /dev/null +++ b/bitcoingraph/logger.py @@ -0,0 +1,25 @@ +import logging +import os + +logging.basicConfig(format='%(levelname)s::%(filename)s:%(asctime)s::%(message)s') +root_logger = logging.getLogger("bitcoingraph") + +LOGLEVEL = os.environ.get('BCG_LOGLEVEL', 'INFO').upper() +root_logger.setLevel(LOGLEVEL) +cached_loggers = {} + +def get_logger(name): + global cached_loggers + logger = cached_loggers.get(name) + if logger is not None: + return logger + + logger = root_logger.getChild(name) + + formatter = logging.Formatter('[%(levelname)s]-[%(name)s]-[%(asctime)s]-%(message)s') + stream_handler = logging.StreamHandler() + stream_handler.setFormatter(formatter) + logger.addHandler(stream_handler) + logger.propagate = False + + return logger \ No newline at end of file diff --git a/bitcoingraph/model.py b/bitcoingraph/model.py index 6c082f8..c3197e5 100755 --- a/bitcoingraph/model.py +++ b/bitcoingraph/model.py @@ -1,230 +1,310 @@ +import copy +import dataclasses +import inspect +import pydantic +from pydantic import BaseModel, validator, field_validator, model_validator +from typing import Optional, List, Union, Dict from bitcoingraph.helper import to_time -class Block: +class ScriptPubKey(BaseModel): + type: str + address: Optional[str] = pydantic.Field(default=None) + asm: Optional[str] = pydantic.Field(default=None) - def __init__(self, blockchain, hash=None, height=None, json_data=None): - self._blockchain = blockchain - if json_data is None: - self.__hash = hash - self.__height = height - self.__timestamp = None - self.__has_previous_block = None - self.__has_next_block = None - self.__transactions = None - self.__difficulty = None - else: - self.__hash = json_data['hash'] - self.__height = json_data['height'] - self.__timestamp = json_data['time'] - self.__difficulty = json_data['difficulty'] - if 'previousblockhash' in json_data: - self.__has_previous_block = True - self.__previous_block = Block(blockchain, json_data['previousblockhash'], - self.height - 1) - else: - self.__has_previous_block = False - self.__previous_block = None - if 'nextblockhash' in json_data: - self.__has_next_block = True - self.__next_block = Block(blockchain, json_data['nextblockhash'], self.height + 1) - else: - self.__has_next_block = False - self.__next_block = None - self.__transactions = [ - Transaction(blockchain, self, tx) if isinstance(tx, str) - else Transaction(blockchain, self, json_data=tx) - for tx in json_data['tx']] +class Output(BaseModel): + txid: str + value: float + index: int = pydantic.Field(alias="n") + script_pub_key: ScriptPubKey = pydantic.Field(alias="scriptPubKey") - @property - def hash(self): - if self.__hash is None: - self._load() - return self.__hash @property - def height(self): - if self.__height is None: - self._load() - return self.__height - + def type(self) -> str: + return self.script_pub_key.type @property - def timestamp(self): - if self.__timestamp is None: - self._load() - return self.__timestamp + def addresses(self) -> List[str]: + if (address := self.script_pub_key.address) is not None: + return [address] + # Check if scriptPubKey.type indicates P2PK transaction, we then extract the pubkey as address from asm object + # which is in the format of ' OP_CHECKSIG' + elif self.type == 'pubkey': + return ['pk_' + self.script_pub_key.asm[0:130]] + else: + return [] +class AbstractInput(BaseModel): @property - def difficulty(self): - if self.__difficulty is None: - self._load() - return self.__difficulty + def is_coinbase(self): + return False - def formatted_time(self): - return to_time(self.timestamp) +class CoinbaseInput(AbstractInput): + coinbase: str @property - def previous_block(self): - self.has_previous_block() - return self.__previous_block + def is_coinbase(self): + return True + +class Input(AbstractInput): + txid: str + vout: int + output_reference: Optional[Output] = pydantic.Field(None) + + @model_validator(mode="before") + def setup_output_reference(cls, obj: Dict) -> Dict: + new_obj = copy.deepcopy(obj) + if prevout := obj.get('prevout', {}): + new_obj['output_reference'] = {} + new_obj['output_reference']['txid'] = obj['txid'] + new_obj['output_reference']['n'] = obj['vout'] + new_obj['output_reference']['value'] = prevout['value'] + new_obj['output_reference']['scriptPubKey'] = prevout['scriptPubKey'] + return new_obj + +class Transaction(BaseModel): + txid: str + inputs: List[Union[Input, CoinbaseInput]] = pydantic.Field(alias="vin") + outputs: List[Output] = pydantic.Field(alias="vout") + + @model_validator(mode="before") + def setup_txid_in_vout(cls, obj: Dict) -> Dict: + """ + We need to pass the txid along to the vout + """ + new_obj = copy.deepcopy(obj) + for vout in new_obj["vout"]: + vout["txid"] = new_obj["txid"] + return new_obj - def has_previous_block(self): - if self.__has_previous_block is None: - self._load() - return self.__has_previous_block + def is_coinbase(self): + try: + return self.inputs[0].is_coinbase + except Exception: + print(f"Couldn't load transaction {self.txid}") + return False + +class Block(BaseModel): + hash: str + height: int + time: int + difficulty: float + tx: List[Transaction] + previous_block_hash: Optional[str] = pydantic.Field(None, alias="previousblockhash") + next_block_hash: Optional[str] = pydantic.Field(None, alias="nextblockhash") + + class Config: + extra = "ignore" @property - def next_block(self): - self.has_next_block() - return self.__next_block - - def has_next_block(self): - if self.__has_next_block is None: - self._load() - return self.__has_next_block + def timestamp(self): + return self.time @property def transactions(self): - if self.__transactions is None: - self._load() - return self.__transactions + return self.tx - def _load(self): - if self.__hash is None: - block = self._blockchain.get_block_by_height(self.__height) - else: - block = self._blockchain.get_block_by_hash(self.__hash) - self.__height = block.height - self.__hash = block.hash - self.__timestamp = block.timestamp - self.__has_previous_block = block.has_previous_block() - self.__previous_block = block.previous_block - self.__has_next_block = block.has_next_block() - self.__next_block = block.next_block - self.__transactions = block.transactions - self.__difficulty = block.difficulty - - -class Transaction: - - def __init__(self, blockchain, block=None, txid=None, json_data=None): - self._blockchain = blockchain - self.block = block - if json_data is None: - self.txid = txid - self.__inputs = None - self.__outputs = None - else: - self.txid = json_data['txid'] - if block is None: - self.block = Block(blockchain, json_data['blockhash']) - self.__inputs = [ - Input(blockchain, is_coinbase=True) if 'coinbase' in vin - else Input(blockchain, vin) - for vin in json_data['vin']] - self.__outputs = [Output(self, i, vout) for i, vout in enumerate(json_data['vout'])] + def has_previous_block(self): + return self.previous_block_hash is not None - @property - def inputs(self): - if self.__inputs is None: - self._load() - return self.__inputs + def has_next_block(self): + return self.next_block_hash is not None - @property - def outputs(self): - if self.__outputs is None: - self._load() - return self.__outputs + def formatted_time(self): + return to_time(self.timestamp) - def _load(self): - transaction = self._blockchain.get_transaction(self.txid) - self.__inputs = transaction.inputs - self.__outputs = transaction.outputs - def is_coinbase(self): - return self.inputs[0].is_coinbase - - def input_sum(self): - return sum([input.output.value for input in self.inputs]) - - def output_sum(self): - return sum([output.value for output in self.outputs]) - - def aggregated_inputs(self): - aggregated_inputs = {} - for input in self.inputs: - output = input.output - if input.is_coinbase: - aggregated_inputs['COINBASE'] = self.output_sum() - elif output.addresses[0] in aggregated_inputs: - aggregated_inputs[output.addresses[0]] += output.value - else: - aggregated_inputs[output.addresses[0]] = output.value - return aggregated_inputs - - def aggregated_outputs(self): - aggregated_outputs = {} - for output in self.outputs: - if output.addresses: - if output.addresses[0] in aggregated_outputs: - aggregated_outputs[output.addresses[0]] += output.value - else: - aggregated_outputs[output.addresses[0]] = output.value - return aggregated_outputs - - @staticmethod - def _reduced_values(values, other_values): - reduced_values = {} - for address, value in values.items(): - if address in other_values: - other_value = other_values[address] - if value > other_value: - reduced_values[address] = value - other_value - else: - reduced_values[address] = value - return reduced_values - - def reduced_inputs(self): - return self._reduced_values(self.aggregated_inputs(), self.aggregated_outputs()) - - def reduced_outputs(self): - return self._reduced_values(self.aggregated_outputs(), self.aggregated_inputs()) - - -class Input: - - def __init__(self, blockchain, output_reference=None, is_coinbase=False): - self._blockchain = blockchain - self.output_reference = output_reference - self.is_coinbase = is_coinbase - self.__output = None - @property - def output(self): - if self.is_coinbase: - return None - if self.__output is None: - self._load() - return self.__output - - def _load(self): - transaction = self._blockchain.get_transaction(self.output_reference['txid']) - self.__output = transaction.outputs[self.output_reference['vout']] - - -class Output: - - def __init__(self, transaction, index, json_data): - self.transaction = transaction - self.index = index - self.value = json_data['value'] - self.type = json_data['scriptPubKey']['type'] - if 'addresses' in json_data['scriptPubKey']: - self.addresses = json_data['scriptPubKey']['addresses'] - # Check if scriptPubKey.type indicates P2PK transaction, we then extract the pubkey as address from asm object - # which is in the format of ' OP_CHECKSIG' - elif json_data['scriptPubKey']['type'] == 'pubkey': - self.addresses = ['pk_' + json_data['scriptPubKey']['asm'][0:130]] - else: - self.addresses = [] +# class Block: +# +# def __init__(self, blockchain, hash=None, height=None, json_data=None): +# self._blockchain = blockchain +# if json_data is None: +# self.__hash = hash +# self.__height = height +# self.__timestamp = None +# self.__has_previous_block = None +# self.__has_next_block = None +# self.__transactions = None +# self.__difficulty = None +# else: +# self.__hash = json_data['hash'] +# self.__height = json_data['height'] +# self.__timestamp = json_data['time'] +# self.__difficulty = json_data['difficulty'] +# if 'previousblockhash' in json_data: +# self.__has_previous_block = True +# self.__previous_block = Block(blockchain, json_data['previousblockhash'], +# self.height - 1) +# else: +# self.__has_previous_block = False +# self.__previous_block = None +# if 'nextblockhash' in json_data: +# self.__has_next_block = True +# self.__next_block = Block(blockchain, json_data['nextblockhash'], self.height + 1) +# else: +# self.__has_next_block = False +# self.__next_block = None +# self.__transactions = [ +# Transaction(blockchain, self, tx) if isinstance(tx, str) +# else Transaction(blockchain, self, json_data=tx) +# for tx in json_data['tx']] +# +# @property +# def hash(self): +# if self.__hash is None: +# self._load() +# return self.__hash +# +# @property +# def height(self): +# if self.__height is None: +# self._load() +# return self.__height +# +# @property +# def timestamp(self): +# if self.__timestamp is None: +# self._load() +# return self.__timestamp +# +# @property +# def difficulty(self): +# if self.__difficulty is None: +# self._load() +# return self.__difficulty +# +# def formatted_time(self): +# return to_time(self.timestamp) +# +# @property +# def previous_block(self): +# self.has_previous_block() +# return self.__previous_block +# +# def has_previous_block(self): +# if self.__has_previous_block is None: +# self._load() +# return self.__has_previous_block +# +# @property +# def next_block(self): +# self.has_next_block() +# return self.__next_block +# +# def has_next_block(self): +# if self.__has_next_block is None: +# self._load() +# return self.__has_next_block +# +# @property +# def transactions(self): +# if self.__transactions is None: +# self._load() +# return self.__transactions +# +# def _load(self): +# raise NotImplementedError("This function has been removed") +# if self.__hash is None: +# block = self._blockchain.get_block_by_height(self.__height) +# else: +# block = self._blockchain.get_block_by_hash(self.__hash) +# self.__height = block.height +# self.__hash = block.hash +# self.__timestamp = block.timestamp +# self.__has_previous_block = block.has_previous_block() +# self.__previous_block = block.previous_block +# self.__has_next_block = block.has_next_block() +# self.__next_block = block.next_block +# self.__transactions = block.transactions +# self.__difficulty = block.difficulty + + +# class Transaction: +# +# def __init__(self, blockchain, block=None, txid=None, json_data=None): +# self._blockchain = blockchain +# self.block = block +# if json_data is None: +# self.txid = txid +# self.__inputs = None +# self.__outputs = None +# else: +# self.txid = json_data['txid'] +# if block is None: +# self.block = Block(blockchain, json_data['blockhash']) +# self.__inputs = [ +# Input(blockchain, is_coinbase=True) if 'coinbase' in vin +# else Input(blockchain, vin) +# for vin in json_data['vin']] +# self.__outputs = [Output(self, i, vout) for i, vout in enumerate(json_data['vout'])] +# +# @property +# def inputs(self): +# if self.__inputs is None: +# self._load() +# return self.__inputs +# +# @property +# def outputs(self): +# if self.__outputs is None: +# self._load() +# return self.__outputs +# +# def _load(self): +# transaction = self._blockchain.get_transaction(self.txid) +# self.__inputs = transaction.inputs +# self.__outputs = transaction.outputs +# +# def is_coinbase(self): +# try: +# return self.inputs[0].is_coinbase +# except Exception: +# print(f"Couldn't load transaction {self.txid}") +# return False +# +# def input_sum(self): +# return sum([input.output.value for input in self.inputs]) +# +# def output_sum(self): +# return sum([output.value for output in self.outputs]) +# +# +# +# class Input: +# +# def __init__(self, blockchain, output_reference=None, is_coinbase=False): +# self._blockchain = blockchain +# self.output_reference = output_reference +# self.is_coinbase = is_coinbase +# self.__output = None +# +# @property +# def output(self): +# if self.is_coinbase: +# return None +# if self.__output is None: +# self._load() +# return self.__output +# +# def _load(self): +# transaction = self._blockchain.get_transaction(self.output_reference['txid']) +# self.__output = transaction.outputs[self.output_reference['vout']] + +# +# class Output: +# +# def __init__(self, transaction, index, json_data): +# self.transaction = transaction +# self.index = index +# self.value = json_data['value'] +# self.type = json_data['scriptPubKey']['type'] +# # See https://github.com/btcsuite/btcd/issues/1874 +# if 'address' in json_data['scriptPubKey']: +# self.addresses = [json_data['scriptPubKey']['address']] +# # Check if scriptPubKey.type indicates P2PK transaction, we then extract the pubkey as address from asm object +# # which is in the format of ' OP_CHECKSIG' +# elif json_data['scriptPubKey']['type'] == 'pubkey': +# self.addresses = ['pk_' + json_data['scriptPubKey']['asm'][0:130]] +# else: +# self.addresses = [] diff --git a/bitcoingraph/neo4j.py b/bitcoingraph/neo4j.py index a9a9324..2b8d4f3 100644 --- a/bitcoingraph/neo4j.py +++ b/bitcoingraph/neo4j.py @@ -1,6 +1,3 @@ - -import json -import requests from datetime import date, datetime, timezone @@ -19,19 +16,9 @@ def __str__(self): class Neo4jController: - def __init__(self, host, port, user, password): - self.host = host - self.port = port - self.user = user - self.password = password - self.url_base = 'http://{}:{}/db/data/'.format(host, port) - self.url = self.url_base + 'transaction/commit' - self.headers = { - 'Accept': 'application/json; charset=UTF-8', - 'Content-Type': 'application/json', - 'max-execution-time': 30000 - } - self._session = requests.Session() + def __init__(self, driver: 'neo4j.Driver'): + self.driver = driver + address_match = lb_join( 'MATCH (a:Address {address: {address}})<-[:USES]-(o),', @@ -125,20 +112,20 @@ def transaction_relations(self, address, address2, date_from, date_to): def entity_query(self, address): s = lb_join( 'MATCH (a:Address {address: {address}})-[:BELONGS_TO]->(e)', - 'RETURN {id: id(e)}') + 'RETURN {id: elementId(e)}') return self.query(s, {'address': address}) def get_number_of_addresses_for_entity(self, id): s = lb_join( 'MATCH (e:Entity)', - 'WHERE id(e) = {id}', + 'WHERE elementId(e) = $id', 'RETURN size((e)<-[:BELONGS_TO]-())') return self.query(s, {'id': id}).single_result() def entity_address_query(self, id, limit): s = lb_join( 'MATCH (e:Entity)<-[:BELONGS_TO]-(a)', - 'WHERE id(e) = {id}', + 'WHERE elementId(e) = $id', 'OPTIONAL MATCH (a)-[:HAS]->(i)', 'WITH e, a, collect(i) as is', 'ORDER BY length(is) desc', @@ -149,7 +136,7 @@ def entity_address_query(self, id, limit): def identity_query(self, address): s = lb_join( 'MATCH (a:Address {address: {address}})-[:HAS]->(i)', - 'RETURN collect({id: id(i), name: i.name, link: i.link, source: i.source})') + 'RETURN collect({id: elementId(i), name: i.name, link: i.link, source: i.source})') return self.query(s, {'address': address}) def reverse_identity_query(self, name): @@ -167,14 +154,14 @@ def identity_add_query(self, address, name, link, source): def identity_delete_query(self, id): s = lb_join( 'MATCH (i:Identity)', - 'WHERE id(i) = {id}', + 'WHERE elementId(i) = $id', 'DETACH DELETE i') return self.query(s, {'id': id}) def path_query_old(self, address1, address2): s = lb_join( - 'MATCH (start:Address {address: {address1}})<-[:USES]-(o1:Output)', - ' -[:INPUT|OUTPUT*]->(o2:Output)-[:USES]->(end:Address {address: {address2}}),', + 'MATCH (start:Address {address: $address1})<-[:USES]-(o1:Output)', + ' -[:INPUT|OUTPUT*]->(o2:Output)-[:USES]->(end:Address {address: $address2}),', ' p = shortestpath((o1)-[:INPUT|OUTPUT*]->(o2))', 'WITH p', 'LIMIT 1', @@ -183,101 +170,86 @@ def path_query_old(self, address1, address2): 'RETURN n as node, a as address') return self.query(s, {'address1': address1, 'address2': address2}) - def path_query(self, address1, address2): - source = self.get_id_of_address_node(address1) - if source is None: - raise Neo4jException("address {} doesn't exist".format(address1)) - target = self.get_id_of_address_node(address2) - if target is None: - raise Neo4jException("address {} doesn't exist".format(address2)) - url = self.url_base + 'ext/Entity/node/{}/findPathWithBidirectionalStrategy'.format(source) - payload = {'target': self.url_base + 'node/{}'.format(target)} - r = self._session.post(url, auth=(self.user, self.password), json=payload, - headers=self.headers) - result_obj = r.json() - result = json.loads(result_obj) if type(result_obj) is str else result_obj - if 'errors' in result: - raise Neo4jException(result['errors'][0]['message']) - elif 'path' in result: - return result['path'] - else: - return None - def get_id_of_address_node(self, address): s = lb_join( - 'MATCH (a:Address {address: {address}})', - 'RETURN id(a)') + 'MATCH (a:Address {address: $address})', + 'RETURN elementId(a)') return self.query(s, {'address': address}).single_result() def get_max_block_height(self): s = lb_join( 'MATCH (b:Block)', - 'RETURN max(b.height)') - return self.query(s).single_result() + 'RETURN max(b.height) as maxHeight') + return self.query(s).single_result()["maxHeight"] def add_block(self, block): s = lb_join( - 'CREATE (b:Block {hash: {hash}, height: {height}, timestamp: {timestamp}})', - 'RETURN id(b)') + 'CREATE (b:Block {hash: $hash, height: $height, timestamp: $timestamp})', + 'WITH b', + 'OPTIONAL MATCH (bprev:Block {height: $height-1})', + 'CALL { WITH b,bprev', + 'WITH b, bprev WHERE bprev is not null', + 'CREATE (b)-[:APPENDS]->(bprev)', + '}' + 'RETURN elementId(b) as id') p = {'hash': block.hash, 'height': block.height, 'timestamp': block.timestamp} return self.query(s, p).single_result() def add_transaction(self, block_node_id, tx): s = lb_join( - 'MATCH (b) WHERE id(b) = {id}', - 'CREATE (b)-[:CONTAINS]->(t:Transaction {txid: {txid}, coinbase: {coinbase}})', - 'RETURN id(t)') - p = {'id': block_node_id, 'txid': tx.txid, 'coinbase': tx.is_coinbase()} + 'MATCH (b) WHERE elementId(b) = $id', + 'CREATE (b)-[:CONTAINS]->(t:Transaction {txid: $txid, coinbase: $coinbase})', + 'RETURN elementId(t) as id') + p = {'id': block_node_id['id'], 'txid': tx.txid, 'coinbase': tx.is_coinbase()} return self.query(s, p).single_result() def add_input(self, tx_node_id, output_reference): s = lb_join( - 'MATCH (o:Output {txid_n: {txid_n}}), (t)', - 'WHERE id(t) = {id}', + 'MATCH (o:Output {txid_n: $txid_n}), (t)', + 'WHERE elementId(t) = $id', 'CREATE (o)-[:INPUT]->(t)') p = {'txid_n': '{}_{}'.format(output_reference['txid'], output_reference['vout']), - 'id': tx_node_id} + 'id': tx_node_id['id']} return self.query(s, p).single_result() def add_output(self, tx_node_id, output): s = lb_join( - 'MATCH (t) WHERE id(t) = {id}', + 'MATCH (t) WHERE elementId(t) = $id', 'CREATE (t)-[:OUTPUT]->' - '(o:Output {txid_n: {txid_n}, n: {n}, value: {value}, type: {type}})', - 'RETURN id(o)') - p = {'id': tx_node_id, 'txid_n': '{}_{}'.format(output.transaction.txid, output.index), + '(o:Output {txid_n: $txid_n, n: $n, value: $value, type: $type})', + 'RETURN elementId(o) as id') + p = {'id': tx_node_id['id'], 'txid_n': '{}_{}'.format(output.transaction.txid, output.index), 'n': output.index, 'value': output.value, 'type': output.type} return self.query(s, p).single_result() def add_address(self, output_node_id, address): s = lb_join( - 'MATCH (o) WHERE id(o) = {id}', - 'MERGE (a:Address {address: {address}})', + 'MATCH (o) WHERE elementId(o) = $id', + 'MERGE (a:Address {address: $address})', 'CREATE (o)-[:USES]->(a)', - 'RETURN id(a)') - return self.query(s, {'id': output_node_id, 'address': address}).single_result() + 'RETURN elementId(a) as id') + return self.query(s, {'id': output_node_id['id'], 'address': address}).single_result() - def create_entity(self, transaction_node_id): - url = self.url_base + 'ext/Entity/node/{}/createEntity'.format(transaction_node_id) - self._session.post(url, auth=(self.user, self.password)) - - def create_entities(self, block_node_id): - url = self.url_base + 'ext/Entity/node/{}/createEntities'.format(block_node_id) - self._session.post(url, auth=(self.user, self.password)) + def add_addresses(self, output_node_id, addresses): + s = lb_join( + 'MATCH (o) WHERE elementId(o) = $id', + 'WITH o', + 'UNWIND $addresses AS address', + 'MERGE (a:Address {address: address})', + 'CREATE (o)-[:USES]->(a)', + 'RETURN elementId(a)') + return self.query(s, {'id': output_node_id['id'], 'addresses': addresses}).single_result() def query(self, statement, parameters=None): - #print(statement, '||', parameters) - statement_json = {'statement': statement} - if parameters is not None: - statement_json['parameters'] = parameters - payload = {'statements': [statement_json]} - r = self._session.post(self.url, auth=(self.user, self.password), - headers=self.headers, json=payload) - result = r.json() - if result['errors']: - raise Neo4jException(result['errors'][0]['message']) - #print(result) - return QueryResult(result) + if parameters is None: + parameters = {} + try: + with self.driver.session() as session: + r = session.run(statement, **parameters) + return QueryResult(r.data()) + + except Exception as e: + raise Neo4jException(str(e)) @staticmethod def as_address_query_parameter(address, date_from=None, date_to=None): @@ -294,24 +266,35 @@ def as_address_query_parameter(address, date_from=None, date_to=None): timestamp_to = d.timestamp() return {'address': address, 'from': timestamp_from, 'to': timestamp_to} - def transaction(self): - return DBTransaction(self.host, self.port, self.user, self.password) + def transaction(self) -> 'DBTransaction': + return DBTransaction(self.driver) class DBTransaction(Neo4jController): def __enter__(self): - transaction_begin_url = self.url_base + 'transaction' - r = self._session.post(transaction_begin_url, auth=(self.user, self.password), - headers=self.headers) - self.url = r.headers['Location'] + self.session = self.driver.session() + tx = self.session.begin_transaction() + self.tx = tx return self - def __exit__(self, type, value, traceback): - transaction_commit_url = self.url + '/commit' - r = self._session.post(transaction_commit_url, auth=(self.user, self.password), - headers=self.headers) - self._session.close() + def __exit__(self, exception_type, value, traceback): + if exception_type is None: + self.tx.commit() + else: + self.tx.rollback() + self.tx.close() + self.session.close() + + def query(self, statement, parameters=None): + if parameters is None: + parameters = {} + try: + r = self.tx.run(statement, **parameters) + return QueryResult(r.data()) + + except Exception as e: + raise Neo4jException(str(e)) class QueryResult: @@ -319,11 +302,9 @@ class QueryResult: def __init__(self, raw_data): self._raw_data = raw_data + @property def data(self): - if self._raw_data['results']: - return self._raw_data['results'][0]['data'] - else: - return [] + return self._raw_data def columns(self): return self._raw_data['results'][0]['columns'] @@ -335,8 +316,8 @@ def list(self): return [r['row'][0] for r in self.data()] def single_result(self): - if self.data(): - return self.data()[0]['row'][0] + if self.data: + return self.data[0] else: return None diff --git a/bitcoingraph/writer.py b/bitcoingraph/writer.py index cd75cac..f6c4a52 100644 --- a/bitcoingraph/writer.py +++ b/bitcoingraph/writer.py @@ -1,20 +1,20 @@ import csv import os +from bitcoingraph.model import Block + class CSVDumpWriter: - def __init__(self, output_path, plain_header=False, separate_header=True): + def __init__(self, output_path): self._output_path = output_path - self._plain_header = plain_header - self._separate_header = separate_header if not os.path.exists(output_path): os.makedirs(output_path) - self._write_header('blocks', ['hash:ID(Block)', 'height:int', 'timestamp:int', 'difficulty:double']) + self._write_header('blocks', ['hash:ID(Block)', 'height:long', 'timestamp:long', 'difficulty:double']) self._write_header('transactions', ['txid:ID(Transaction)', 'coinbase:boolean']) - self._write_header('outputs', ['txid_n:ID(Output)', 'n:int', 'value:double', 'type']) + self._write_header('outputs', ['txid_n:ID(Output)', 'n:long', 'value:double', 'type']) self._write_header('addresses', ['address:ID(Address)']) self._write_header('rel_block_tx', ['hash:START_ID(Block)', 'txid:END_ID(Transaction)']) self._write_header('rel_block_block', ['hash:START_ID(Block)', 'prevblockhash:END_ID(Block)']) @@ -35,15 +35,15 @@ def __enter__(self): self._rel_input_file = open(self._get_path('rel_input'), 'a') self._rel_output_address_file = open(self._get_path('rel_output_address'), 'a') - self._block_writer = csv.writer(self._blocks_file) - self._transaction_writer = csv.writer(self._transactions_file) - self._output_writer = csv.writer(self._outputs_file) - self._address_writer = csv.writer(self._addresses_file) - self._rel_block_tx_writer = csv.writer(self._rel_block_tx_file) - self._rel_block_block_writer = csv.writer(self._rel_block_block_file) - self._rel_tx_output_writer = csv.writer(self._rel_tx_output_file) - self._rel_input_writer = csv.writer(self._rel_input_file) - self._rel_output_address_writer = csv.writer(self._rel_output_address_file) + self._block_writer = csv.writer(self._blocks_file, lineterminator="\n") + self._transaction_writer = csv.writer(self._transactions_file, lineterminator="\n") + self._output_writer = csv.writer(self._outputs_file, lineterminator="\n") + self._address_writer = csv.writer(self._addresses_file, lineterminator="\n") + self._rel_block_tx_writer = csv.writer(self._rel_block_tx_file, lineterminator="\n") + self._rel_block_block_writer = csv.writer(self._rel_block_block_file, lineterminator="\n") + self._rel_tx_output_writer = csv.writer(self._rel_tx_output_file, lineterminator="\n") + self._rel_input_writer = csv.writer(self._rel_input_file, lineterminator="\n") + self._rel_output_address_writer = csv.writer(self._rel_output_address_file, lineterminator="\n") return self def __exit__(self, type, value, traceback): @@ -57,26 +57,22 @@ def __exit__(self, type, value, traceback): self._rel_output_address_file.close() def _write_header(self, filename, row): - if self._separate_header: - filename += '_header' + filename += '_header' with open(self._get_path(filename), 'w') as f: writer = csv.writer(f) - if self._plain_header: - header = [entry.partition(':')[0] for entry in row] - else: - header = row + header = row writer.writerow(header) def _get_path(self, filename): return os.path.join(self._output_path, filename + '.csv') - def write(self, block): + def write(self, block: Block): def a_b(a, b): return '{}_{}'.format(a, b) self._block_writer.writerow([block.hash, block.height, block.timestamp, block.difficulty]) if block.has_previous_block(): - self._rel_block_block_writer.writerow([block.hash, block.previous_block.hash]) + self._rel_block_block_writer.writerow([block.hash, block.previous_block_hash]) for tx in block.transactions: self._transaction_writer.writerow([tx.txid, tx.is_coinbase()]) @@ -85,7 +81,7 @@ def a_b(a, b): for input in tx.inputs: self._rel_input_writer.writerow( [tx.txid, - a_b(input.output_reference['txid'], input.output_reference['vout'])]) + a_b(input.output_reference.txid, input.output_reference.index)]) for output in tx.outputs: self._output_writer.writerow([a_b(tx.txid, output.index), output.index, output.value, output.type]) diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..f3bfda8 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,20 @@ +version: '2.4' +services: + + neo4j: + image: neo4j:5.8 + container_name: neo4j_db + ports: + - 7474:7474 + - 7687:7687 + environment: + NEO4J_apoc_export_file_enabled: "true" + NEO4J_apoc_import_file_enabled: "true" + NEO4J_apoc_import_file_use__neo4j__config: "true" + NEO4J_dbms_security_auth__enabled: "false" + NEO4J_dbms_allow__upgrade: "true" + NEO4JLABS_PLUGINS: "[\"apoc\"]" + NEO4J_AUTH: neo4j/localtest + volumes: +# - ./scripts/blocks-full/:/opt/local/data + - ./scripts/blocks/:/opt/local/data diff --git a/docs/documentation.md b/docs/documentation.md new file mode 100644 index 0000000..48a4e33 --- /dev/null +++ b/docs/documentation.md @@ -0,0 +1,197 @@ +# Table of contents +- [Neo4j pointers and examples](#neo4j-pointers) +- [Using your own bitcoin node](#own-bitcoin-node) +- [Compute entities extended explanation](#entities-process) +- [SSH Paramiko Config Example](#ssh-config) + + +## Hardware requirements + +**Network**: Before anything else, you will have to download the entire blockchain up to the last block that interests +you. In July 2023 the full blockchain is a download of about 525 GiB. You will need this on the same machine (or at +least on the same LAN) as bitcoingraph and your neo4j database. + +**Storage**: Exporting the blockchain and importing it into neo4j does some very intensive I/O. You are advised to use +the fastest possible NVMe for writing and, whenever possible, separate reading from writing onto different storage +devices. In a first step you will run bitcoind and dump the entire blockchain into various CSV files. You can easily put +bitcoind and its BTC blocks on a traditional metal HDD (the full blockchain with indices and other auxiliary files is +about 575 GiB in July 2023), but you should be writing the CSV files on a different device, preferably an NVMe. A neo4j +database of the full blockchain (again, July 2023) will need more than 2 TB and less than 4 TB of storage space. Big Fat +Warning: do NOT use any copy-on-write or snapshotting filesystem. If you do, you will completely ruin performance. Even +journaling should probably be turned off until the neo4j database is ready and running. + +**CPU**: Some (but not all) bitcoingraph processes, most notably the import into neo4j, can use multiple CPUs in +parallel. Then again, the more CPUs that you use, the more likely it is that you will run into your storage's read/write +limits. If you use metal HDDs, one or two CPU cores should be enough. If you use fast NVMes you can experiment with four +to eight cores, also depending on the speed of your CPU. + +**RAM**: This is the most expensive part of this operation. For a full blockchain import (July 2023) into neo4j you will +need at least 48 GB of RAM, most likely even more. The original bcgraph-compute-entities +from [source](https://github.com/behas/bitcoingraph/tree/master/scripts) consumed more than 230 GB of RAM for an entities +computation of blocks 0-675000. The current version can do the same job with about 60 GB of RAM. You can +try to tweak this back and for some marginal gains, but you will never achieve any acceptable speed on a low-memory +system. Or any results at all, other than a crash, without altering the code. A wet-finger-in-the-air recommendation is +64 GB of RAM at the very least, preferably more. + + + +## Neo4j pointers + +- Before running a large query, always run the query with `EXPLAIN` first. This shows the plan of the database calls, + and can be very useful to notice a suboptimal query +- Don't be scared of using `WITH` to aggregate results during the query, it can save a lot of time. For example + ```cypher + MATCH (a:Address) + OPTIONAL MATCH (a)<-[:OWNER_OF]-(e:Entity) + WHERE a.address in ["123","456",..] + RETURN a,e + ``` + looks like a good query. However, running it with explain will immediately show that the optional match actually + matches all of the addresses (completely ignoring the `WHERE` condition). Instead, the correct use would be + ```cypher + MATCH (a:Address) + WHERE a.address in ["123","456",..] + WITH a + OPTIONAL MATCH (a)<-[:OWNER_OF]-(e:Entity) + RETURN a,e + ``` +- Use transactions on large queries, both for read and writes: + ```cypher + MATCH (a:Address) + CALL { + // do something with the addresses + } IN TRANSACTION OF 1000 ROWS + ``` + +### Example queries + +Get the sum of bitcoins that passed through a given address. + +```cypher +MATCH (a:Address) +WHERE a.address = "1234" +WITH a +MATCH (a)<-[:USES]-(o:Output) +RETURN a.address, sum(o.value) +``` + +also account for what went through all the entities + +```cypher +MATCH (a:Address) +WHERE a.address = "1234" +WITH a +MATCH (a)<-[:USES]-(o:Output) +OPTIONAL MATCH (a)<-[:OWNER_OF]-()-[:OWNER_OF]->(connected_a)<-[:USES]-(connected_o:Output) +WHERE connected_a <> a +RETURN a.address, sum(o.value)+sum(connected_o.value) +``` + + + +## Using your own Bitcoin node + +it is recommended to run your own bitcoin, however you should look at whether you have the right hardware for that. + +### Bitcoin Core setup and configuration + +First, install the current version of Bitcoin Core: + +`dnf install \'bitcoin-core\*\'` +`apt-get install bitcoind bitcoin-qt bitcoin-tx` + +Make sure the version is `bitcoind >= 0.22` + +You can also install from [source](https://github.com/bitcoin/bitcoin) or from a +[pre-compiled executable](https://bitcoin.org/en/download) if you are so inclined. + +Once installed, you'll have access to three programs: `bitcoind` (= full peer), `bitcoin-qt` (= peer with GUI), +and `bitcoin-cli` (RPC command line interface). + +Depending on how you installed bitcoind, you will find a sample configuration +file somewhere, perhaps as /usr/share/doc/bitcoin-core-server/bitcoin.conf.example. +Place a copy of it in $HOME/.bitcoin/bitcoin.conf as the user who will run +bitcoind and edit it at least as follows: + + # server=1 tells Bitcoin-QT to accept JSON-RPC commands. + server=1 + + # You must set rpcauth to secure the JSON-RPC api. rpcauth and rpcpassword + # are obsolete. Use rcpauth.py from your bitcoind installation or from + # [github]https://github.com/bitcoin/bitcoin/blob/master/share/rpcauth/rpcauth.py + # to create the password hash. + #rpcuser=your_rpcuser + #rpcpassword=your_rpcpass + rcpauth=your_rpcuser:password_hash + + # How many seconds bitcoin will wait for a complete RPC HTTP request. + # after the HTTP connection is established. + rpctimeout=300 + + # Listen for RPC connections on this TCP port: + rpcport=8332 + + # Index non-wallet transactions (required for fast txn and block lookups) + txindex=1 + + # Enable unauthenticated REST API + rest=1 + + # Do NOT enable pruning + prune=0 + + # Configure this if you don't have 800-900 GB free space in the + # bitcoind user's home directory + datadir=/path/to/lots/of/free/space + +If you already had a working bitcoind with some blocks but without indexing, +run `bitcoind -reindex` before anything else. + +Now you should be able to start and run a Bitcoin Core peer as follows: + + `bitcoind -printtoconsole` + +Test whether the JSON-RPC interface is working by starting your Bitcoin Core peer (...waiting until it finished +startup...) and using the following cURL request (with adapted username and password): + + `curl --data-binary '{"jsonrpc": "1.0", "id":"curltext", "method": "getblockchaininfo", "params": [] }' -H 'content-type: text/plain;' http://your_rpcuser:your_rpcpass@localhost:8332/` + +Test non-wallet transaction data access by taking an arbitrary transaction id and issuing the following request: + + `curl --data-binary '{"jsonrpc": "1.0", "id":"curltext", "method": "getrawtransaction", "params": ["110ed92f558a1e3a94976ddea5c32f030670b5c58c3cc4d857ac14d7a1547a90", 1] }' -H 'content-type: text/plain;' http://your_rpcuser:your_rpcpass@localhost:8332/` + +Test the REST interface using some sample block hash + + http://localhost:8332/rest/block/000000000000000e7ad69c72afc00dc4e05fc15ae3061c47d3591d07c09f2928.json + +When you have reached this point, your Bitcoin Core setup is working. You can let it run on, +or relaunch it as a background daemon with `bitcoind -daemon`. + + + +## Compute entities extended documentation +Higher up in the README, we explained what an entity is. Computing entities is a simple +process fundamentally, made very hard due to the size of the files. +We use two files: rel_input.csv and rel_output_address.csv. The first is in +chronological order, and the second is sorted by Output id. + +The objective is two-fold: 1. for each output, find the address, and 2. if two addresses +are inputs to the same transaction, create an entity (or merge if one of the two is already +part of an entity). + +The `bcgraph-compute-entities` is basically a database specialized for this very specific +file format and objective. + + + +## Paramiko SSH config example +```json +{ + "hostname":"127.0.0.1", + "port":7472, + "username":"username", + "password":"password", + "allow_agent":false, + "look_for_keys":false +} +``` \ No newline at end of file diff --git a/docs/graph.png b/docs/graph.png new file mode 100644 index 0000000..efb24ce Binary files /dev/null and b/docs/graph.png differ diff --git a/entities_process.sh b/entities_process.sh new file mode 100755 index 0000000..6b0cd80 --- /dev/null +++ b/entities_process.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# Check if the path is provided +if [ -z "$1" ]; then + echo "Error: No path provided. Please provide a path as an argument." + exit 1 +fi + +path="$1" + +# You can add further actions using the provided path here +echo "Path provided: $path" + +chmod +x scripts/bcgraph-compute-entities +chmod +x scripts/bcgraph-pk-to-addresses + +./scripts/bcgraph-compute-entities -i $path +./scripts/bcgraph-pk-to-addresses -i $path + +cd scripts/merge-entities && cargo build --release && cd ../.. +./scripts/merge-entities/target/release/merge_entities $path/rel_entity_address.csv $path/rel_entity_address_merged.csv diff --git a/requirements.txt b/requirements.txt index d7669d4..fc6fd2e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,6 @@ -requests>=2.5.0 -beautifulsoup4 -pytest +bitcoinlib~=0.6.10 +cryptography~=41.0.1 +neo4j~=5.9.0 +pydantic~=2.3.0 +requests~=2.31.0 +tqdm~=4.65.0 diff --git a/scripts/bc-daemon.py b/scripts/bc-daemon.py new file mode 100755 index 0000000..e635cf8 --- /dev/null +++ b/scripts/bc-daemon.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python + +import argparse +import queue +import sys +from time import sleep + +from bitcoingraph.bitcoingraph import BitcoinGraph +from bitcoingraph.blockchain import BlockchainException +from bitcoingraph.logger import get_logger +logger = get_logger("bc-daemon") + +parser = argparse.ArgumentParser( + description='Synchronise database with blockchain') +parser.add_argument('-s', '--bc-host', required=True, + help='Bitcoin Core host') +parser.add_argument('--bc-port', default='8332', + help='Bitcoin Core port') +parser.add_argument('-u', '--bc-user', required=True, + help='Bitcoin Core RPC username') +parser.add_argument('-p', '--bc-password', required=True, + help='Bitcoin Core RPC password') +parser.add_argument('--rest', action='store_true', + help='Prefer REST API over RPC. This is only possible on localhost.') +parser.add_argument('-S', '--neo4j-host', required=True, + help='Neo4j host') +parser.add_argument('--neo4j-port', default='7687', + help='Neo4j port') +parser.add_argument('-U', '--neo4j-user', required=True, + help='Neo4j username') +parser.add_argument('-P', '--neo4j-password', required=True, + help='Neo4j password') +parser.add_argument('--neo4j-protocol', default="bolt://", + help='Neo4j protocol. Defaults to bolt://') +parser.add_argument('-b', '--max-height', type=int, default=1_000_000_000_000, + help='Max block height to reach') +parser.add_argument('-l', '--lag', type=int, required=True, + help='How many blocks to keep in safety buffer in case of re-organisation') + + +def thread_synchronization(bcgraph: BitcoinGraph, max_height: int, queue_new_block: queue.Queue, + queue_stop: queue.Queue): + + while True: + try: + # check whether we received a stop signal from the daemon + if not queue_stop.empty(): + return + + for height in bcgraph.synchronize(max_height): + queue_new_block.put(height) + + except BlockchainException as e: + print(f"Blockchain error: {e}. Trying again soon") + + except StopIteration: + print("Finished synchronize") + break + + finally: + # try again in 5 seconds + sleep(5) + + queue_new_block.put(None) + +def thread_wrapper(f, data_queue: queue.Queue, stop_queue: queue.Queue): + while True: + try: + data = data_queue.get_nowait() + f(data) + + except queue.Empty: + if not stop_queue.empty(): + return + sleep(0.5) + + +seen_addresses = set([]) + +def main(bc_host, bc_port, bc_user, bc_password, rest, neo4j_host, neo4j_port, neo4j_user, neo4j_password, + neo4j_protocol, max_height, lag): + blockchain = {'host': bc_host, 'port': bc_port, + 'rpc_user': bc_user, 'rpc_pass': bc_password} + if rest: + blockchain['method'] = 'REST' + neo4j_cfg = {'host': neo4j_host, 'port': neo4j_port, + 'user': neo4j_user, 'pass': neo4j_password} + + if lag <= 4: + logger.warn(f"You have chosen a lag of {lag} which is below the recommended 5. This is considered dangerous as, " + f"if there's any re-organisation of the block maximum-{lag}, then the block will already have been " + f"loaded on neo4j, and it will crash the daemon. The latest blocks will have to be manually removed " + f"and added again. It is strongly recommended to keep a lag > 4") + if input("I understand the risk and want to proceed [y/n]").strip().lower() != "y": + logger.info("Exiting") + sys.exit() + + + finished_sync = False + bcgraph = BitcoinGraph(blockchain=blockchain, neo4j=neo4j_cfg) + logger.info(f"Starting daemon. Running with max height {max_height}") + try: + while True: + for _ in bcgraph.synchronize(max_height, lag): + finished_sync = False + + if not finished_sync: + finished_sync = True + logger.info("Finished syncing, sleeping") + + sleep(5) + except StopIteration: + logger.info("Clean exit.") + pass + + +if __name__ == "__main__": + args = parser.parse_args() + main(**vars(args)) diff --git a/scripts/bc-delete-entities.py b/scripts/bc-delete-entities.py new file mode 100755 index 0000000..e7a6c1b --- /dev/null +++ b/scripts/bc-delete-entities.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python + +import argparse +import queue +import threading +from time import sleep + +import neo4j +import tqdm + +from bitcoingraph.address import process_create_pk_to_generated + +parser = argparse.ArgumentParser( + description='Synchronise database with blockchain') + +parser.add_argument('-H', '--host', default='localhost', + help='Neo4j host') +parser.add_argument('-P', '--port', default='7687', + help='Neo4j Bolt port') +parser.add_argument('-u', '--user', required=True, + help='Neo4j username') +parser.add_argument('-p', '--password', required=True, + help='Neo4j password') +parser.add_argument('--protocol', default='bolt://', + help="Protocol to use to connect to db. Default to bolt://") +parser.add_argument('-b', '--batch-size', default=50, type=int, + help='Number of blocks to query at the same time') +parser.add_argument('--start-height', default=0, type=int, + help='At which block to start') +parser.add_argument('--max-height', default=None, type=int, + help="At which block to end") + + +def thread_get_entities_per_block(session: neo4j.Session, max_height: int, batch_size: int, result_queue: queue.Queue, + stop_queue: queue.Queue): + idx = 0 + try: + while stop_queue.empty() and idx < max_height: + result = session.run(""" + MATCH (b:Block) + WHERE b.height >= $lower AND b.height < $higher + WITH b + LIMIT $higher-$lower + MATCH (b)-[:CONTAINS]->()<-[:INPUT]-()-[:USES]->()-[:BELONGS_TO]->(e) + RETURN collect(distinct elementId(e)) as relIds + """, lower=idx, higher=idx + batch_size).data()[0]["relIds"] + result_queue.put(result) + idx += batch_size + + except Exception as e: + print(f"Thread failed: {e}") + finally: + stop_queue.put(True) + result_queue.put(None) + session.close() + + +def thread_delete_entities(session: neo4j.Session, data_queue: queue.Queue, stop_queue: queue.Queue): + is_empty_counter = 0 + try: + while True: + try: + new_entities = data_queue.get_nowait() + print(f"Deleting {len(new_entities)}") + session.run(""" + MATCH (e) + WHERE elementId(e) in $elmIds + DETACH DELETE e + """, elmIds=list(new_entities)) + + except queue.Empty: + sleep(0.5) + if not stop_queue.empty(): + is_empty_counter += 1 + if is_empty_counter > 4: + print("Stopping entities threas") + break + finally: + session.close() + return + + +def main(host, port, user, password, batch_size, start_height, max_height, protocol): + driver = neo4j.GraphDatabase.driver(f"{protocol}{host}:{port}", + auth=(user, password), + connection_timeout=3600) + + result_queue = queue.Queue() + stop_queue = queue.Queue() + thread_session = driver.session() + + if max_height is None: + max_height = thread_session.run("MATCH (b:Block) RETURN max(b.height) as maxHeight").data()[0]["maxHeight"] + + print(f"Running with {start_height} <= height < {max_height}") + + thread = threading.Thread(target=thread_get_entities_per_block, + args=(thread_session, max_height, batch_size, result_queue, stop_queue,)) + thread.start() + + entities_queue = queue.Queue() + thread = threading.Thread(target=thread_delete_entities, + args=(driver.session(), entities_queue, stop_queue,)) + thread.start() + + session = driver.session() + progress_bar = tqdm.tqdm(total=max_height - start_height) + seen_rels = set([]) + batch_rels = set([]) + try: + while True: + try: + relationships = result_queue.get_nowait() + if relationships is None: + break + + new_rels = set(relationships).difference(seen_rels) + seen_rels.update(new_rels) + if new_rels: + batch_rels.update(new_rels) + if len(batch_rels) >= 2000: + entities_queue.put(batch_rels) + batch_rels = set([]) + + progress_bar.update(batch_size) + progress_bar.set_postfix({"awaiting rels": len(batch_rels)}) + + except queue.Empty: + sleep(0.5) + + except KeyboardInterrupt: + pass + + finally: + entities_queue.put(batch_rels) + stop_queue.put(True) + thread.join() + session.close() + driver.close() + + +if __name__ == "__main__": + args = parser.parse_args() + main(**vars(args)) diff --git a/scripts/bcgraph-add-block-usd-value.py b/scripts/bcgraph-add-block-usd-value.py new file mode 100755 index 0000000..116e97b --- /dev/null +++ b/scripts/bcgraph-add-block-usd-value.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python + +import argparse +import csv +from neo4j import GraphDatabase +from datetime import datetime + +def add_values(driver,first,last,file): + + print("Starting...") + with open(file) as f: + reader = csv.DictReader(f) + dv = list(reader) + + + if not any(d['Date'] == first for d in dv): + raise SystemExit("Your start date is not in the CSV file") + if not any(d['Date'] == last for d in dv): + raise SystemExit("Your end date is not in the CSV file") + + ff = datetime.strptime(first, "%Y-%m-%d") + fl = datetime.strptime(last, "%Y-%m-%d") + if ff > fl: + raise SystemExit("Your start date is later than your end date") + + for d in dv: + date = d['Date'] + valueUSD = float(d['Average']) + ustart = int(d['unixstart']) + uend = int(d['unixend']) + if ff <= datetime.strptime(date, "%Y-%m-%d") <= fl: + print("Adding value to " + date + " blocks") + with driver.session() as session: + result = session.run(""" + MATCH (b:Block) + WHERE b.timestamp >= $ustart AND b.timestamp <= $uend + WITH b + SET b.valueUSD = $valueUSD + RETURN b.height, b.valueUSD + """, ustart=ustart, uend=uend, valueUSD=valueUSD).values() + if len(result) > 0: + r = result + print(f"Added value {r[0][1]} to blocks {r[0][0]} -> {r[-1][0]}") + +parser = argparse.ArgumentParser( + description="Use data from a CSV file in the format 'Date,Average_value,Date_start_unixtime,Date_end_unixtime' " + "(in UTC) to add a USD value to the transactions in a range of blocks. " + "The CSV header expected is 'Date,Average,unixstart,unixend'. A CSV going from 2010 to mid 2023 is " + "provided in the assets folder of the repository. " + "Edit 'valueUSD' in this script to (also) add a value in another currency. " +) +parser.add_argument('--host', default="0.0.0.0", help='Neo4j host') +parser.add_argument('--port', default=7687, help='Neo4j port', type=int) +parser.add_argument('-u', '--username', required=True, help='Neo4j user') +parser.add_argument('-p', '--password', required=True, help='Neo4j password') +parser.add_argument('-F', '--first', required=True, help='First date to process, YYYY-MM-DD') +parser.add_argument('-L', '--last', required=True, help='Last date to process, YYYY-MM-DD') +parser.add_argument('-f', '--file', required=True, help='CSV file to parse') + +def main(): + if __name__ == "__main__": + args = parser.parse_args() + driver = GraphDatabase.driver(f"bolt://{args.host}:{args.port}", + auth=(args.username, args.password), + connection_timeout=3600) + if args.last < args.first: + raise SystemExit('The value of --last cannot be lower than that of --first.') + add_values(driver, args.first, args.last, args.file) + +if __name__ == "__main__": + main() + diff --git a/scripts/bcgraph-compute-entities b/scripts/bcgraph-compute-entities index b1b1b49..8ed1b3b 100755 --- a/scripts/bcgraph-compute-entities +++ b/scripts/bcgraph-compute-entities @@ -1,16 +1,562 @@ #!/usr/bin/env python - import argparse -from bitcoingraph import bitcoingraph +import bisect +import datetime +import io +import os +import pickle +import subprocess +import time +import typing +from collections import OrderedDict +from pathlib import Path +from typing import List, Optional + +from tqdm import tqdm + +from bitcoingraph import entities +from bitcoingraph.entities import EntityGrouping +from bitcoingraph.helper import sort parser = argparse.ArgumentParser( description='Compute entities from exported block chain data') parser.add_argument('-i', '--input_path', required=True, help='Input path') -parser.add_argument('--sort-input', action='store_true', +parser.add_argument('--sort-output', action='store_true', help='Sort all input files. This is necessary if ' 'the transaction deduplication was skipped on export.') +parser.add_argument('--chunk-size', type=int, default=10_000, + help='Size of each "batch". Smaller batch are better up to some extent. Should aim for around 10KB but can be tuned as needed') +parser.add_argument('--read-size', type=int, default=10_000_000, + help='Size to read at at a time from file in bytes. Typical value about 10MB') +parser.add_argument('--cached-batches', type=int, default=5_000, + help='Number of latest processed batches to keep in memory. About 5000 is good') +parser.add_argument('--max-queue-size', type=int, default=1_000_000_000, + help='Most important variable for both performance and memory. The higher the better. ' + 'This is proportional to the memory usage. 5_000_000_000 is about 60G of max RAM used.') + + +class Cache: + cumsum_row: List[int] + lookup_table: List[int] + lookup_keys: List[str] + lookup_cursor: int + + cached_batches: List[List[str]] + cache_cursor: int + cache_txid_start: OrderedDict[str, int] + n_cached_batches: int + chunk_size: int + + def __init__(self, n_cached_batches: int, chunk_size: int, path_to_output_address: Path): + self.cumsum_row = [0] + self.lookup_table: List[int] = [0] * n_cached_batches + self.lookup_keys: List[str] = [""] * n_cached_batches + self.lookup_cursor: int = 0 + + self.cached_batches: List[List[str]] = [[] for _ in range(n_cached_batches)] + self.cache_cursor = 0 + self.cache_txid_start: OrderedDict[str, int] = OrderedDict() + self.n_cached_batches = n_cached_batches + self.chunk_size = chunk_size + self.file: typing.BinaryIO = open(path_to_output_address, "rb") + self.cache_full = False + + def __del__(self): + print("Freeing cache resources") + self.file.close() + + def load_indexes(self, output_address_iterator): + progress = tqdm(output_address_iterator, desc="Indexing output") + for i, (batch, cursor) in enumerate(progress): + self.load_batch(batch, cursor, only_index=True) + if i % 100 == 0: + mb = float(cursor) / 1e3 + progress.set_postfix({"KB read": "{:,.0f}".format(mb)}) + + def get_lookup_index(self, txid_n: str) -> Optional[int]: + left = 0 + right = self.lookup_cursor - 1 + result = -1 # Default result if no match is found + + # if it's greater, we always return None. If it happens to be in the same batch + # as the current greatest batch, it will be caught in the main code + if txid_n >= self.lookup_keys[right]: + return None + + while left <= right: + mid = (left + right) // 2 + + if self.lookup_keys[mid] > txid_n: + result = mid + right = mid - 1 + else: + left = mid + 1 + + return result - 1 + + # @profile + def try_get_cached(self, txid_n: str, index_position: int) -> Optional[str]: + cache_idx = self.cache_txid_start.get(self.lookup_keys[index_position]) + if cache_idx is not None: + return self.find_cached_address(cache_idx, txid_n) + return None + + # @profile + def load_from_file(self, lookup_index: int, txid_n: str, save_batch=True): + tell = self.lookup_table[lookup_index] + self.file.seek(tell) + buffer = self.file.read(self.chunk_size) + buffer += self.file.readline() + decoded = buffer.decode() + batch, cursor = process_chunk(decoded, self.chunk_size, tell) + batch_idx = self.load_batch(batch, cursor, save_batch=save_batch) + address = self.find_cached_address(batch_idx, txid_n) + if address is None: + raise IndexError("load_from_file should always find the address") + return address + + # @profile + def find_cached_address(self, cache_idx: int, txid_n: str) -> Optional[str]: + idx = bisect_right_lambda(self.cached_batches[cache_idx], txid_n, lambda arr_, idx_: arr_[idx_][0]) + x = self.cached_batches[cache_idx][idx - 1] + if x[0] == txid_n: + return x[1] + return None + + # @profile + def load_batch(self, batch: List[List[str]], tell: int, only_index: bool = False, save_batch=True): + txid_n = batch[0][0] + + # This means it's not already loaded + if self.lookup_cursor == 0 or tell > self.lookup_table[self.lookup_cursor - 1]: + if (self.lookup_cursor + 1) % self.n_cached_batches == 0: + self.lookup_table.extend([0] * self.n_cached_batches) + self.lookup_keys.extend([""] * self.n_cached_batches) + + self.lookup_table[self.lookup_cursor] = tell + self.lookup_keys[self.lookup_cursor] = txid_n + self.lookup_cursor += 1 + + if not only_index: + # latest batch are automatically loaded in cache + self.cache_txid_start[txid_n] = self.cache_cursor + if len(self.cache_txid_start) >= self.n_cached_batches: + # keep cache of max size self.n_cached_batches + self.cache_txid_start.popitem(last=False) + + self.cached_batches[self.cache_cursor] = batch + batch_idx = self.cache_cursor + + if save_batch: + self.cache_cursor = (self.cache_cursor + 1) % self.n_cached_batches + if self.cache_cursor == 0 and not self.cache_full: + self.cache_full = True + + return batch_idx + + +def process_line(line): + line = line.strip() + idx = line.find(",") + return line[:idx], line[idx + 1:] + + +def process_chunk(buffer: str, chunk_size: int, cursor: int): + # list comprehensions are known to be faster due to underlying + # optimisation done by CPython (not sure about PyPy) + return [process_line(line) for line in buffer.split("\n") if line], cursor + + +def read_csv_in_chunks(file, chunk_size: int, read_size: int) -> (List[List[str]], int): # 10MB + s = file.read(read_size) + s += file.readline() + # batch_str = io.StringIO(s) + # batch = io.TextIOWrapper(batch_str, encoding='utf-8') + batch = io.BytesIO(s) + file_tell = 0 + while True: + buffer = batch.read(chunk_size).decode() + cursor = file_tell + while buffer: + buffer += batch.readline().decode() # finish the current line + + yield process_chunk(buffer, chunk_size, cursor) + cursor = batch.tell() + file_tell + buffer = batch.read(chunk_size).decode() + + file_tell = file.tell() + tmp = file.read(read_size) + file.readline() + if len(tmp) == 0: + break + batch = io.BytesIO(tmp) + + +def iterate_grouped_outputs(batch): + """ + The batch has structure [[tx1,o11], [tx1,o12], [tx2,o21], [tx3,o31]...]. This generator groups all + the outputs by the transaction, and will yield for example + [o11,o12], + [o21], + [o31] + """ + current_tx = None + current_group = [] + + for item in batch: + tx, o = item + if tx != current_tx: + if current_group: + yield current_tx, current_group, False + current_tx = tx + current_group = [] + current_group.append(o) + + if current_group: + yield current_tx, current_group, True + + +def output_distance(out1, out2): + return int(out1[:4], 16) - int(out2[:4], 16) + + +def bisect_right_lambda(a, x, key): + """Return the index where to insert item x in list a, assuming a is sorted. + + The return value i is such that all e in a[:i] have e <= x, and all e in + a[i:] have e > x. So if x already appears in the list, a.insert(x) will + insert just after the rightmost x already there. + + Optional args lo (default 0) and hi (default len(a)) bound the + slice of a to be searched. + """ + lo = 0 + hi = len(a) + while lo < hi: + mid = (lo + hi) // 2 + # Use __lt__ to match the logic in list.sort() and in heapq + if x < key(a, mid): + hi = mid + else: + lo = mid + 1 + return lo + + +def get_address_of_output(txid_n: str, cache: Cache, output_address_iterator): + idx = cache.get_lookup_index(txid_n) + if idx is not None: + address = cache.try_get_cached(txid_n, idx) + if address is None: + try: + address = cache.load_from_file(idx, txid_n) + except IndexError: + # print("Skipped idx found:", txid_n) + # Can happen when the address was invalid (I suppose due to + # human error in the transaction) + return None + return address + else: + # try to get from latest cache + if cache.lookup_cursor > 0: + tried_lookup = cache.lookup_cursor - 1 + address = cache.try_get_cached(txid_n, tried_lookup) + if address is not None: + return address + + for batch, cursor in output_address_iterator: + batch_idx = cache.load_batch(batch, cursor) + if batch[0][0] <= txid_n <= batch[-1][0]: + address = cache.find_cached_address(batch_idx, txid_n) + if address is not None: + return address + if txid_n < batch[0][0]: + # Last chance, we try to get it from file now + try: + idx = cache.get_lookup_index(txid_n) + if idx: + address = cache.load_from_file(idx, txid_n) + if address is not None: + return address + except IndexError: + # This can happen when the address is "Unknown" (mistake?) + # print("Skipped idx not found:", txid_n) + return None + + +# @profile +def fill_address_group_for_outputs(outputs: List[str], address_group: typing.Set[str], output_address_iterator, + cache: Cache): + if len(outputs) <= 1: + return 0 + + skipped = 0 + for txid_n in outputs: + address = get_address_of_output(txid_n, cache, output_address_iterator) + if address is not None: + address_group.add(address) + else: + skipped += 1 + return skipped + + +def flatten_and_sort_with_index(input_list, bar=None): + # Step 1: Flatten the list of lists + flattened_list = [item for sublist in input_list for item in sublist] + + # Step 2: Create a list of grouping indices + index_list = [i for i, sublist in enumerate(input_list) for _ in range(len(sublist))] + + # Step 3: Sort the flattened list + sorted_list_with_index = sorted(zip(flattened_list, index_list), key=lambda x: int(x[0][:12], 16)) + + # Step 4: Extract the sorted list and the sorted index list + sorted_list, sorted_index_list = zip(*sorted_list_with_index) + + return sorted_list, sorted_index_list + + +def group_back_with_index(sorted_list, sorted_index_list): + # Combine the sorted list and the index list into pairs + combined_list = list(zip(sorted_list, sorted_index_list)) + + # Create a dictionary to group the values based on their index + grouped_values = {} + for value, index in combined_list: + if value is None: + continue + if index not in grouped_values: + grouped_values[index] = [] + grouped_values[index].append(value) + + return grouped_values + + +# @profile +entity_idx_counter = 0 +counter_joined_entities = 0 + + +def process_queue(queued_output_groups: List[List[str]], cache: Cache, + output_address_iterator, input_path): + global entity_idx_counter, counter_joined_entities + entity_grouping = EntityGrouping() + entity_grouping.entity_idx_counter = entity_idx_counter + entity_grouping.counter_joined_entities = counter_joined_entities + + bar = tqdm(desc="Sorting queue") + start = time.time_ns() + queued_output_groups, original_output_idx = flatten_and_sort_with_index(queued_output_groups) + tot = (time.time_ns() - start) / 1e9 + bar.set_postfix({"Time taken": "{:.2f}s".format(tot)}) + bar.close() + # queued_output_groups = sorted(queued_output_groups, key=lambda x: int(x[-1][:5], 16)) + bar = tqdm(queued_output_groups, unit="output", smoothing=0.1, maxinterval=None) + # queued_output_groups.sort(key=lambda x: int(x[-1][:5], 16)) + bar.set_description("Processing queue") + + last_empty = 0 + original_output_idx_to_address = [None] * len(original_output_idx) + skipped = 0 + skipped_outputs = [] + for i, output in enumerate(bar): + address = get_address_of_output(output, cache, output_address_iterator) + if address is None: + skipped += 1 + skipped_outputs.append(output) + original_output_idx_to_address[i] = address + + if i and i % 1000 == 0: + bar.set_postfix({ + # "entities": entity_grouping.entity_idx_counter, + # "joined": entity_grouping.counter_joined_entities, + "max cached index": cache.cached_batches[cache.cache_cursor - 1][0][0][:6], + "cache cursor": cache.cache_cursor, + "lookup size": len(cache.lookup_table), + "skipped": skipped, + "entities": entity_idx_counter, + "joined": counter_joined_entities + }) + + with open(input_path.joinpath("skipped.csv"), "a+") as f_skipped: + f_skipped.write("\n".join(skipped_outputs) + "\n") + + bar.set_description("Grouping outputs back") + grouped = group_back_with_index(original_output_idx_to_address, original_output_idx) + bar.close() + + for (idx, addresses) in tqdm(grouped.items(), desc="Forming entities", total=len(grouped)): + entity_grouping.update_from_address_group(addresses) + if entity_grouping.entity_idx_counter > last_empty + 400_000: + save_entities(entity_grouping.entity_idx_to_addresses, input_path) + entity_idx_counter = entity_grouping.entity_idx_counter + counter_joined_entities = entity_grouping.counter_joined_entities + + entity_grouping = EntityGrouping() + entity_grouping.entity_idx_counter = entity_idx_counter + entity_grouping.counter_joined_entities = counter_joined_entities + last_empty = entity_idx_counter + + save_entities(entity_grouping.entity_idx_to_addresses, input_path) + entity_idx_counter = entity_grouping.entity_idx_counter + counter_joined_entities = entity_grouping.counter_joined_entities + return len(queued_output_groups) + + +def queue_size(queued_output_groups: List[List[str]]) -> int: + # size of outer List + size of inner List + return len(queued_output_groups) * (8 + 64) + (8 + 68 + 64) * len(queued_output_groups) * 3 + + +def save_entities(entity_idx_to_addresses: typing.Dict[int, typing.Set[str]], input_path: Path): + with open(input_path.joinpath(f"rel_entity_address.csv"), "a+") as relationships_csv: + + rel_buffer = "" + for entity_id, addresses in entity_idx_to_addresses.items(): + if addresses is None: + continue + + rel_buffer += "".join([f"{entity_id},{a}\n" for a in addresses if a is not None]) + + # write the buffer in chunks of 1MB + if len(rel_buffer) > 1_000_000: + relationships_csv.write(rel_buffer) + rel_buffer = "" + + relationships_csv.write(rel_buffer) + + +# @profile +def process(input_path: Path, chunk_size: int, cached_batches: int, tot: Optional[int], read_size: int, + max_queue_size: int): + print("Preparing cache") + cache = Cache(n_cached_batches=cached_batches, chunk_size=chunk_size, + path_to_output_address=input_path.joinpath('rel_output_address.csv')) + print("Cache ready") + + with open(input_path.joinpath("skipped.csv"), "w+") as _: + pass + + with open(input_path.joinpath("checkpoint.csv"), "w+") as _: + pass + + try: + size = os.path.getsize(input_path.joinpath("rel_entity_address.csv")) + if size > 100_000: + r = input( + "The output file rel_entity_address.csv already exists, are you sure you want to overwrite it? [y/n]\n") + if r.strip() != "y": + print("Stopping process") + exit(0) + with open(input_path.joinpath("rel_entity_address.csv"), "w+") as _: + pass + + except FileNotFoundError: + pass + + with open(input_path.joinpath("rel_entity_address_header.csv"), "w+") as header: + header.writelines(["entity_id:START_ID(Entity),address:END_ID(Address)"]) + + with open(input_path.joinpath("entity_header.csv"), "w+") as header: + header.writelines(["entity_id:ID(Entity)"]) + + with open(input_path.joinpath('rel_input.csv'), 'rb') as f_rel_input, open( + input_path.joinpath('rel_output_address.csv'), 'rb') as f_rel_output_address: + + iteration = 0 + address_group = set([]) + skipped = 0 + total_count_tx = 0 + + kwargs = {"unit": 'tx', "mininterval": 1, "smoothing": 0.1, "desc": "Loading queue", "maxinterval": None} + if tot is not None: + kwargs["total"] = tot + bar = tqdm(**kwargs) + + output_address_iterator = read_csv_in_chunks(f_rel_output_address, chunk_size, read_size) + + queued_output_groups = [] + + interchunk_transaction_group = None + for input_batch, _ in read_csv_in_chunks(f_rel_input, 5_000_000, max(read_size, 1_000_000_000)): + count_tx = 0 + iterator = iterate_grouped_outputs(input_batch) + + if queue_size(queued_output_groups) > max_queue_size: + bar.close() + with open(input_path.joinpath("checkpoint.csv"), "a+") as f_checkpoint: + f_checkpoint.write(f"{len(queued_output_groups)}\n") + process_queue(queued_output_groups, cache, output_address_iterator, input_path) + queued_output_groups = [] + bar = tqdm(**kwargs, initial=total_count_tx) + + for tx, outputs, leftover in iterator: + if interchunk_transaction_group is not None: + # We need to do this because a transaction group may be + # split into multiple returned batches + if interchunk_transaction_group[0] != tx: + queued_output_groups.append(interchunk_transaction_group[1]) + else: + outputs.extend(interchunk_transaction_group[1]) + + interchunk_transaction_group = None + + if leftover: + interchunk_transaction_group = (tx, outputs) + continue + + if len(outputs) == 1: + count_tx += 1 + continue + + outputs.sort() + queued_output_groups.append(outputs) + count_tx += 1 + + # Statistics section + bar.update(count_tx) + bar.set_postfix({ + "iteration": iteration, + "queue size": "{:.0f}".format(queue_size(queued_output_groups)), + }) + + total_count_tx += count_tx + iteration += 1 + + # if len(address_group) > 1: + # entity_grouping.update_from_address_group(list(address_group)) + + if interchunk_transaction_group: + queued_output_groups.append(interchunk_transaction_group[1]) + + if queued_output_groups: + processed = process_queue(queued_output_groups, cache, output_address_iterator, input_path) + count_tx += processed + queued_output_groups = [] + print("Finished") + + bar.set_postfix({ + "entities": entity_idx_counter, + "joined": counter_joined_entities, + "iteration": iteration, + "skipped": skipped, + "total_tx": total_count_tx + }) + if __name__ == "__main__": args = parser.parse_args() - bitcoingraph.compute_entities(args.input_path, args.sort_input) + + if args.sort_output: + print("Sorting rel_output_address.csv") + sort(args.input_path, 'rel_output_address.csv') + + print("Getting upper bound approximate number of transactions for statistics display") + tx_path = Path(args.input_path).resolve().joinpath("transactions.csv") + tot = int(round(os.path.getsize(tx_path) / 70)) + print("Found {} transactions".format(tot)) + + start = time.time_ns() + process(Path(args.input_path).resolve(), args.chunk_size, args.cached_batches, tot, args.read_size, + args.max_queue_size) + end = time.time_ns() + print((end - start) / 1e9) diff --git a/scripts/bcgraph-export b/scripts/bcgraph-export index cb30e19..bd1badf 100755 --- a/scripts/bcgraph-export +++ b/scripts/bcgraph-export @@ -1,8 +1,14 @@ #!/usr/bin/env python import argparse +import os import sys -from bitcoingraph import BitcoinGraph + +if os.environ.get("BCG_LOGLEVEL") is None: + os.environ["BCG_LOGLEVEL"] = "WARN" + +from bitcoingraph.bitcoingraph import BitcoinGraph +from bitcoingraph.bitcoind import SSHTunnel def progress(p=0): @@ -10,39 +16,56 @@ def progress(p=0): sys.stdout.write('\rProgress: {}%'.format(p)) sys.stdout.flush() + parser = argparse.ArgumentParser( description='Export transactions from blockchain') parser.add_argument('startheight', type=int, help='Start block height') parser.add_argument('endheight', type=int, help='End block height') +parser.add_argument('-r', '--resume', action="store_true", + help='If provided, then start height is ignored and the process is resumed from the last block') parser.add_argument('-o', '--output_path', type=str, help='Output path') -parser.add_argument('--plain-header', action='store_true', - help='Create header without Neo4J field types') -parser.add_argument('--no-separate-header', action='store_true', - help='Write header and data into one CSV file') -parser.add_argument('--no-transaction-deduplication', action='store_true', - help='Skip deduplication of transactions') parser.add_argument("-u", "--user", required=True, help="Bitcoin Core RPC username") parser.add_argument("-p", "--password", required=True, help="Bitcoin Core RPC password") +parser.add_argument("-H", "--host", default="localhost", + help="Bitcoin Core host") +parser.add_argument("-P", "--port", default=8332, type=int, + help="Bitcoin Core port") +parser.add_argument("--ssh", + help="Path containing paramiko ssh configs in json format") +parser.add_argument("--cache", type=str, + help="Directory path. Uses the directory to save/fetch already downloaded blocks. Useful only for " + "development/debugging purposes") +parser.add_argument("--timeout", type=int, + help="Bitcoin Core request timeout") +parser.add_argument("--sort-only", default=False, action="store_true", + help="Skip processing and only sort output csv files") + +if __name__ == "__main__": + if len(sys.argv) <= 1: + parser.print_help() + sys.exit(1) + + args = parser.parse_args() + + ssh_tunnel = args.ssh + if ssh_tunnel: + ssh_tunnel = SSHTunnel.from_config_file(args.ssh) + + bcgraph = BitcoinGraph( + blockchain={'host': args.host, 'port': args.port, + 'rpc_user': args.user, 'rpc_pass': args.password, + 'method': 'REST', 'cache_path': args.cache, 'ssh_tunnel': ssh_tunnel, + 'timeout': args.timeout}) -if len(sys.argv) <= 1: - parser.print_help() - sys.exit(1) - -args = parser.parse_args() -bcgraph = BitcoinGraph( - blockchain={'host': 'localhost', 'port': 8332, - 'rpc_user': args.user, 'rpc_pass': args.password, - 'method': 'REST'}) -bcgraph.export( - args.startheight, - args.endheight, - args.output_path, - args.plain_header, - not args.no_separate_header, - progress, - not args.no_transaction_deduplication) + bcgraph.export( + args.startheight, + args.endheight, + args.output_path, + progress, + args.sort_only, + args.resume) diff --git a/scripts/bcgraph-pk-to-addresses b/scripts/bcgraph-pk-to-addresses new file mode 100755 index 0000000..5be4c83 --- /dev/null +++ b/scripts/bcgraph-pk-to-addresses @@ -0,0 +1,193 @@ +#!/usr/bin/env python + +import argparse +import datetime +import pathlib +import sys +import os +import shutil +from bitcoinlib.keys import Key + +parser = argparse.ArgumentParser( + description='Compute entities from exported block chain data') +parser.add_argument('-i', '--input_path', required=True, + help='Input path') +parser.add_argument('-b', '--batch_size', required=False, default=1000, type=int, + help='Write batch size') +parser.add_argument('-r', '--read-size', required=False, default=4294967296, type=int, + help='Read batch size. Defaults to 4GB') + + +def get_p2pkh(k: Key): + return k.address() + + +def get_p2wpkh(k: Key): + return k.address(compressed=True, encoding="bech32") + + +def progress(p: float): + p = int(p * 100) + sys.stdout.write('\rProgress: {}%'.format(p)) + sys.stdout.flush() + + +def line_reader(file, chunk_size): + remainder = "" # Store the remaining data from the previous chunk + while True: + start = datetime.datetime.now() + print(f"Reading batch of {chunk_size} bytes") + chunk = file.read(chunk_size) + if not chunk: + print(f"EOF") + break + end = datetime.datetime.now() + print(f"Batch read in {(end-start).seconds} seconds") + data = remainder + chunk + lines = data.split("\n") + # Process all complete lines except the last one + for line in lines[:-1]: + yield line.strip() + remainder = lines[-1] + + if remainder: + yield remainder + + +if __name__ == "__main__": + args = parser.parse_args() + batch_size = args.batch_size + path = pathlib.Path(args.input_path) + + with open(path.joinpath("rel_address_address_header.csv"), "w+") as f: + f.write("pk:START_ID(Address),address:END_ID(Address)\n") + + print("Starting..") + chunk_size = args.read_size + started_processing_pk = False + + path_rel_address_address = path.joinpath("rel_address_address.csv") + path_rel_entity_address = path.joinpath("rel_entity_address.csv.tmpcopy") + path_rel_entity_address_original = path.joinpath("rel_entity_address.csv") + + with open(path.joinpath("pk2addresses.csv"), "w+") as _: + pass + with open(path.joinpath("new_addresses.csv"), "w+") as _: + pass + with open(path_rel_address_address, "w+") as _: + pass + + with open(path_rel_entity_address_original) as f: + f.seek(0,os.SEEK_END) + f.seek(f.tell()-500) + lines = f.readlines() + current_entity_id = int(lines[-1].split(",")[0]) + 1 + + print("Create copy of rel_entity_address.csv") + shutil.copy(path_rel_entity_address_original, path_rel_entity_address) + + + with open(path.joinpath("addresses.csv"), "r") as fa: + # instead of writing every relationship one at a time, we write them in batches + batch_write_rel_address_address = [] + batch_write_rel_entity_address = [] + for line_number, line in enumerate(line_reader(fa, chunk_size)): + if line.startswith("pk_"): + if line.endswith("CHECKSIG"): + pk = line[3:-12] + else: + pk = line[3:] + + if not started_processing_pk: + started_processing_pk = True + print("Started processing public keys") + + try: + key = Key(pk) + except Exception as e: + print(f"Failed to parse key, skipping\n{pk}\n{e}") + continue + + p2pkh = get_p2pkh(key) + p2wpkh = get_p2wpkh(key) + batch_write_rel_address_address.extend([ + f"{line},{p2pkh}", f"{line},{p2wpkh}" + ]) + batch_write_rel_entity_address.extend([ + f"{current_entity_id},{line}", + f"{current_entity_id},{p2pkh}", + f"{current_entity_id},{p2wpkh}" + ]) + current_entity_id += 1 + + if line_number and batch_write_rel_address_address and line_number % batch_size == 0: + date = datetime.datetime.utcnow() + print(f'{date.strftime("%Y-%m-%d %H:%M:%S")} Processed {line_number} addresses') + + with open(path_rel_address_address, "a") as output: + output.write("\n".join(batch_write_rel_address_address) + "\n") + + with open(path_rel_entity_address, "a") as output: + output.write("\n".join(batch_write_rel_entity_address) + "\n") + batch_write_rel_address_address = [] + batch_write_rel_entity_address = [] + + if batch_write_rel_address_address: + with open(path_rel_address_address, "a") as output: + output.write("\n".join(batch_write_rel_address_address) + "\n") + fa.close() + + pkh_addresses = [] + pk_lines = 0 + print("Reading pk2pkh addresses") + with open(path_rel_address_address, "r") as fr: + for line_number, line in enumerate(line_reader(fr, chunk_size)): + address = line.rsplit(",", 1)[-1] + pkh_addresses.append(address) + pk_lines += 1 + fr.close() + + print("Finding duplicate addresses") + pkh_addresses.sort() + to_remove = [] + with open(path.joinpath("addresses.csv")) as f: + read_address = f.readline().strip() + file_has_content = True + for i,address in enumerate(pkh_addresses): + while file_has_content: + if read_address == address: + to_remove.append(i) + break + elif read_address > address: + break + + read_address = f.readline().strip() + if len(read_address) == 0: + file_has_content = False + + print(f"Found {len(to_remove)} addresses to remove") + for i in reversed(to_remove): + pkh_addresses.pop(i) + + + print("Writing pk2pkh addresses") + with open(path.joinpath("pk2addresses.csv"), "w") as pka: + pka.writelines((addr+"\n" for addr in pkh_addresses)) + pka.close() + + + + print("Appending pk2pkh addresses to addresses") + addrfiles = [path.joinpath("addresses.csv"), path.joinpath("pk2addresses.csv")] + with open(path.joinpath("new_addresses.csv"), "wb") as ba: + for af in addrfiles: + with open(af,'rb') as fd: + shutil.copyfileobj(fd, ba) + + print("Keep original addresses.csv in case of error as addresses.csv.original") + shutil.move(path.joinpath("addresses.csv"), path.joinpath("addresses.csv.original")) + shutil.move(path.joinpath("new_addresses.csv"), path.joinpath("addresses.csv")) + + print("Keep original rel_entity_address.csv in case of error as rel_entity_address.csv.original") + shutil.move(path_rel_entity_address_original, path.joinpath("rel_entity_address.csv.original")) + shutil.move(path_rel_entity_address, path_rel_entity_address_original) diff --git a/scripts/bcgraph-synchronize b/scripts/bcgraph-synchronize index dd66bcd..c89d4e5 100755 --- a/scripts/bcgraph-synchronize +++ b/scripts/bcgraph-synchronize @@ -1,7 +1,8 @@ #!/usr/bin/env python import argparse -from bitcoingraph import BitcoinGraph + +from bitcoingraph.bitcoingraph import BitcoinGraph parser = argparse.ArgumentParser( description='Synchronise database with blockchain') @@ -17,7 +18,7 @@ parser.add_argument('--rest', action='store_true', help='Prefer REST API over RPC. This is only possible on localhost.') parser.add_argument('-S', '--neo4j-host', required=True, help='Neo4j host') -parser.add_argument('--neo4j-port', default='7474', +parser.add_argument('--neo4j-port', default='7687', help='Neo4j port') parser.add_argument('-U', '--neo4j-user', required=True, help='Neo4j username') @@ -27,12 +28,18 @@ parser.add_argument('-b', '--max-blocks', type=int, help='Enforce a limit on the number of blocks that are synchronised') -args = parser.parse_args() -blockchain = {'host': args.bc_host, 'port': args.bc_port, - 'rpc_user': args.bc_user, 'rpc_pass': args.bc_password} -if args.rest: - blockchain['method'] = 'REST' -neo4j = {'host': args.neo4j_host, 'port': args.neo4j_port, - 'user': args.neo4j_user, 'pass': args.neo4j_password} -bcgraph = BitcoinGraph(blockchain=blockchain, neo4j=neo4j) -bcgraph.synchronize(args.max_blocks) +def main(): + args = parser.parse_args() + blockchain = {'host': args.bc_host, 'port': args.bc_port, + 'rpc_user': args.bc_user, 'rpc_pass': args.bc_password} + if args.rest: + blockchain['method'] = 'REST' + neo4j = {'host': args.neo4j_host, 'port': args.neo4j_port, + 'user': args.neo4j_user, 'pass': args.neo4j_password} + bcgraph = BitcoinGraph(blockchain=blockchain, neo4j=neo4j) + for _ in bcgraph.synchronize(args.max_blocks): + continue + + +if __name__ == "__main__": + main() diff --git a/scripts/find_path_between_entities b/scripts/find_path_between_entities new file mode 100755 index 0000000..89835d6 --- /dev/null +++ b/scripts/find_path_between_entities @@ -0,0 +1,713 @@ +#!/usr/bin/env python + +import argparse +import dataclasses +import logging +import pathlib +import pickle +import time +import uuid +from datetime import datetime +from queue import Queue +from threading import Thread +from typing import List, Set, Dict, Tuple + +import treelib.exceptions +from neo4j import GraphDatabase +from treelib import Tree + +RUN_ID = uuid.uuid4() +logger: logging.Logger = None +transaction_logger: logging.Logger = None + +def setup_logging(): + global RUN_ID, logger, transaction_logger + logging.basicConfig( + level=logging.INFO, + format='%(asctime)s %(levelname)s: %(message)s', + ) + logger = logging.getLogger("entities") + logger.setLevel(logging.INFO) + + file_handler = logging.FileHandler(f"track-bitcoin-output-{datetime.utcnow().isoformat()}-{RUN_ID}.log") + logger.addHandler(file_handler) + + transaction_logger = logging.getLogger("transactions") + file_handler = logging.FileHandler(f"track-bitcoin-transactions-{RUN_ID}.log") + transaction_logger.addHandler(file_handler) + transaction_logger.propagate = False + + +# @profile +def run_query(session, txid, result_queue, query): + # Replace the following query with your specific query, using txid as a parameter + result = session.run(query, txid=txid) + result_queue.put((txid, result.values())) + session.close() +def wrapper(idx, f, input_queue_: Queue, queue, session): + while True: + input = input_queue_.get() + if input is None: + break + else: + ret = f(session, input) + queue.put((idx, ret)) + +# @profile +def parallel_execution(driver, thread_function, kill_queue, iterable, main_queue: Queue): + + + threads = [] + result_queues = [Queue() for _ in range(20)] + sessions = [driver.session() for i in range(20)] + input_queues = [Queue() for _ in range(20)] + try: + for i in range(20): + thread = Thread(target=wrapper, args=(i, thread_function, input_queues[i], result_queues[i], sessions[i])) + thread.start() + threads.append(thread) + + + for i, elm in enumerate(iterable): + if not kill_queue.empty(): + logger.info("Received thread kill signal. Stopping") + break + sent = False + if i < 20: + input_queues[i].put(elm) + continue + + while True: + for queue in result_queues: + if not queue.empty(): + idx, result = queue.get() + input_queues[idx].put(elm) + main_queue.put(result) + # yield result + sent=True + break + if sent: + break + time.sleep(0.1) + + for queue in input_queues: + queue.put(None) + + # Wait for all threads to finish + for thread in threads: + thread.join() + + # Yield the results from the queue + for result_queue in result_queues: + while not result_queue.empty(): + rows = result_queue.get()[1] + main_queue.put(rows) + # yield rows + + finally: + # try to make as clean an exit as possible + main_queue.put(None) + for queue in input_queues: + queue.put(None) + [session.close() for session in sessions] + +class Walker(Tree): + garbage: Set[str] + txids: Set[str] + + def __init__(self): + super().__init__() + self.garbage = set([]) + self.create_node(identifier="root") + self.txids = set([]) + + def add_root(self, output: str, data=None): + try: + self.create_node(identifier=output, parent="root", data=data) + except treelib.exceptions.DuplicatedNodeIdError: + pass + + def get_path(self, node_id): + path = [] + node = self.get_node(node_id) + if node is None: + return None # Node not found + while node is not None: + path.append(node.identifier) + if node and node.data and node.data.get("entity"): + address = node.data["address"] + path.append(f"Entity[{address}]") + + node = self.parent(node.identifier) + + + return list(reversed(path)) + + + def remove_path(self, identifier): + node = self.get_node(identifier) + if node is None: + logger.warning(f"Trying to remove unknown identifier: {identifier}") + else: + if node.data: + node.data["end"] = True + else: + node.data = {"end": True} + # try: + # parent = self.parent(identifier) + # except treelib.exceptions.NodeIDAbsentError: + # return 0 + # if len(self.children(parent.identifier)) == 1 and parent.identifier != "root": + # return self.remove_path(parent.identifier) + # else: + # deleted = self.remove_node(identifier) + # return deleted + + + def add_to_garbage(self, identifier: str): + self.garbage.add(identifier) + + def empty_garbage(self): + for identifier in self.garbage: + node = self.get_node(identifier) + if node and len(self.children(identifier)) == 0: + logger.debug(f"Removing {identifier}") + self.remove_path(identifier) + +class InputWalker(Walker): + def get_next_input(self): + # we don't iterate of leaves directly since it can change as the loop goes on. This + # way we get a snapshot + leaves = list(self.leaves()) + for node in leaves: + if node.data and node.data.get("end") == True: + continue + + if "_" not in node.identifier: + yield node.identifier + + def expand_node(self, txid: str, new_output: str, dollar_amount, address): + if self.get_node(new_output) is None: + self.create_node(identifier=new_output, parent=txid, data={"$": dollar_amount, "address": address}) + return True + else: + return False + + def expand_transactions(self): + leaves = list(self.leaves()) + for leaf in leaves: + txid = leaf.identifier.split("_")[0] + + if txid in self.txids: + self.remove_path(leaf.identifier) + else: + self.txids.add(txid) + self.create_node(identifier=txid, parent=leaf.identifier) + + def process_input(self, txid, rows, end_addresses): + if not rows: + self.remove_path(txid) + return + row = rows[0] + ts = row[1] + price = get_average_price(ts) + for (txid_n, value, address) in row[2]: + if address in end_addresses: + logger.info("Found destination") + self.expand_node(txid, txid_n, value * price, address) + logger.info(self.get_path(txid_n)) + exit(0) + if not self.expand_node(txid, txid_n, value * price, address): + # implies the path is already checked and is therefore dead + self.add_to_garbage(txid) + + def add_entity_connection(self, output: str, address: str): + if self.get_node(output) is not None: + return + parent = next(self.filter_nodes(lambda x: x.data and x.data.get("address") == address and x.data.get("entity") != True)) + self.create_node(identifier=output, parent=parent, data={"entity": True, "address": address}) + +class OutputWalker(Walker): + def add_entity_connection(self, rows): + for row in rows: + txid_n, address, new_txid = row + if self.get_node(txid_n) is not None or self.get_node(new_txid) is not None: + continue + + parent = next(self.filter_nodes(lambda x: x.data and x.data.get("address") == address and x.data.get("entity") != True)) + self.create_node(identifier=txid_n, parent=parent, data={"entity": True, "address": address}) + self.create_node(identifier=new_txid, parent=txid_n) + + def process_output(self, txid, rows, through_entity=False): + if not rows and txid != 'root': + self.remove_path(txid) + return + + for row in rows: + txid_n, address, new_txid = row + node_txid_n = self.get_node(txid_n) + if node_txid_n is None: + data = {"address": address} + if through_entity: + data["entity"] = True + self.create_node(identifier=txid_n, parent=txid, data=data) + + if new_txid in self.txids: + continue + self.txids.add(new_txid) + node_txid = self.get_node(new_txid) + if node_txid is None: + self.create_node(identifier=new_txid, parent=txid_n) + else: + self.remove_path(new_txid) + + def get_next_output(self): + # we don't iterate of leaves directly since it can change as the loop goes on. This + # way we get a snapshot + leaves = list(self.leaves()) + for node in leaves: + if node.data and node.data.get("end") == True: + continue + + if "_" not in node.identifier: + yield node.identifier + + def get_latest_addresses(self): + addresses = set([]) + for leaf in self.leaves(): + if leaf.data is not None and leaf.data.get("end") == True: + continue + + node = self.parent(leaf.identifier) + if node.data is None or node.data.get("address") is None: + continue + + addresses.add(node.data["address"]) + return addresses +class Summary: + def __init__(self): + self.expanded_transactions = 0 + self.depth = 1 + + +def path_to_query(input_path, output_path): + query = "MATCH path=" + previous = None + + path = input_path + list(reversed(output_path[1:-1])) + + len_input_path = len(input_path) + for i,e in enumerate(path): + if e == "root": + query += "(:Entity)-[:OWNER_OF]->(:Address)" + previous = "root" + elif "_" in e: + if previous == "root" or previous == "entity": + query += "<-[:USES]-" + elif previous == "tx": + query += "<-[:INPUT]-" + query += f"(:Output {{txid_n: '{e}'}})" + previous = "output" + + elif "Entity" in e: + address = e.split("[")[1].split("]")[0] + # The only difference between the input and output direction, is whether the entity address + # is to the left or right of the entity. + if i < len_input_path: + query += f"-[:USES]->(:Address {{ address: '{address}'}})<-[:OWNER_OF]-(:Entity)-[:OWNER_OF]->(:Address)" + else: + query += f"-[:USES]->(:Address)<-[:OWNER_OF]-(:Entity)-[:OWNER_OF]->(:Address {{ address: '{address}'}})" + previous = "entity" + + else: + query += f"<-[:OUTPUT]-(:Transaction {{ txid: '{e}' }})" + previous = "tx" + + query += "-[:USES]->(:Address)<-[:OWNER_OF]-(:Entity) RETURN path" + return query + +MIN_AMOUNT: int = None +def input_thread_function(session, txid): + global MIN_AMOUNT + logger.debug(f"Running on {txid}") + query_template = """ + MATCH (a:Address)<-[:USES]-(input:Output)-[:INPUT]->(t:Transaction {txid: $txid})<-[:CONTAINS]-(b:Block) + WHERE input.value > $min_value + WITH collect([input.txid_n, input.value, a.address]) as tuple, t,b + WITH t.txid as txid,b.timestamp as ts,tuple + RETURN txid, ts, tuple + """ + try: + ts = session.run("MATCH (t:Transaction {txid: $txid})<-[:CONTAINS]-(b:Block) RETURN b.timestamp as ts", txid=txid).single().get("ts") + except AttributeError: + logger.warning(f"How can {txid} not have a block?!") + return None + btc_price = get_average_price(ts) + result = session.run(query_template, txid=txid, min_value=MIN_AMOUNT/btc_price) + return txid, True, result.values() + +def output_thread_function(session, txid): + global MIN_AMOUNT + logger.debug(f"Running on {txid}") + + results = session.run( + """MATCH (:Transaction {txid: $txid})-[:OUTPUT]->(output:Output)-[:INPUT]->(t:Transaction)<-[:CONTAINS]-(b:Block) + WITH output, b.timestamp as ts, t.txid as txid + MATCH (output)-[:USES]->(a:Address) + RETURN output.txid_n as txid_n, output.value as value, a.address as address, ts, txid + """ + , txid=txid + ).values() + + tuples = [] + for row in results: + if get_average_price(row[3])*row[1] > MIN_AMOUNT: + # txid_n, address, txid + tuples.append((row[0], row[2], row[4])) + return txid, False, tuples + + +@dataclasses.dataclass +class Context: + input_walker: InputWalker + output_walker: OutputWalker + # transactions in current batch + transactions: List[str] + output_transactions: List[str] + # transactions in current batch that were already processed + done_transactions: Set[str] + previous_transactions: Set[str] + start: str + end: str + end_addresses: Set[str] + address_to_outputs: Dict[str, List[str]] + curr_depth: int + max_depth: int + min_amount: int + ignore_entities: bool + log_transactions: bool + # When the context is created, this should be set to False. Only at the moment of saving should it be temporarily + # set to True. This way, when we resume, we can correctly interpret the data + resumed: bool + + +def get_inputs_through_entity(session, addresses: List[str]) -> Dict[str, List[str]]: + query_through_entity = """ + MATCH (a:Address)<-[:OWNER_OF]-()-[r:OWNER_OF]->() + WHERE a.address in $addresses + WITH a, count(r) as cr + WHERE cr < 1000 + CALL { + WITH a + MATCH (a)<-[:OWNER_OF]-()-[:OWNER_OF]->(b:Address)<-[r:USES]-() + WHERE a <> b + WITH a, count(r) as cr + WHERE cr < 1000 + MATCH (a)<-[:OWNER_OF]-()-[:OWNER_OF]->(b:Address)<-[:USES]-(o:Output) + RETURN a.address as address, collect(distinct o.txid_n) as txid_n + } IN TRANSACTIONS OF 100 ROWS + RETURN address, txid_n + """ + address_to_outputs = {} + + rows = session.run(query_through_entity, addresses=list(addresses)).values() + + if rows and rows[0] and rows[0][0]: + for row in rows: + address, txid_n = row + address_to_outputs[address] = txid_n + + return address_to_outputs + + +def get_outputs_through_entity(session, addresses: List[str]) -> List[Tuple[str, str, str]]: + query_through_entity = """ + MATCH (a:Address)<-[:OWNER_OF]-()-[r:OWNER_OF]->() + WHERE a.address in $addresses + WITH a, count(r) as cr + WHERE cr < 1000 + CALL { + WITH a + MATCH (a)<-[:OWNER_OF]-()-[:OWNER_OF]->(b:Address)<-[r:USES]-() + WHERE a <> b + WITH a, count(r) as cr + WHERE cr < 1000 + MATCH (a)<-[:OWNER_OF]-()-[:OWNER_OF]->(:Address)<-[:USES]-(o:Output)-[:INPUT]->(t:Transaction)<-[:CONTAINS]-(block:Block) + RETURN o.txid_n as txid_n, a.address as address, t.txid as txid, o.value as value, block.timestamp as ts + } IN TRANSACTIONS OF 1000 ROWS + RETURN txid_n, address, txid, value, ts + """ + + result = session.run(query_through_entity, addresses=list(addresses)).values() + rows = [] + for row in result: + if get_average_price(row[4]) * row[3] < MIN_AMOUNT: + continue + rows.append((row[0], row[1], row[2])) + return rows + + +def track_output(driver, context: Context): + global MIN_AMOUNT + MIN_AMOUNT=context.min_amount + start_time = time.time() + + logger.info(f"Start walk. Run id: {RUN_ID}") + # with driver.session() as session: + summary = Summary() + last_save = time.time() + previous_transactions = context.previous_transactions + output_transactions = [] + try: + for depth in range(context.curr_depth,context.max_depth): + added_through_entity = 0 + if not context.ignore_entities and not context.resumed: + with driver.session() as session: + addresses = {l.data["address"] for l in context.input_walker.leaves() if l.data is not None and l.data.get("end") != True} + if addresses: + logger.info(f"Expanding entities through 'input' entities: {len(addresses)} addresses") + logger.debug(f"Getting outputs through entity for {addresses}") + address_to_outputs = get_inputs_through_entity(session, list(addresses)) + for address, outputs in address_to_outputs.items(): + for o in outputs: + added_through_entity += 1 + context.input_walker.add_entity_connection(o, address) + + addresses = context.output_walker.get_latest_addresses() + if addresses: + logger.info(f"Expanding entities through 'output' entities: {len(addresses)} addresses") + logger.debug(f"Getting outputs through entity for {addresses}") + rows = get_outputs_through_entity(session, list(addresses)) + context.output_walker.add_entity_connection(rows) + + + if context.resumed: + transactions = list(set(context.transactions).difference(context.done_transactions)) + output_transactions = list(set(context.output_transactions).difference(context.done_transactions)) + else: + context.input_walker.expand_transactions() + + logger.info("Preparing next transactions") + transactions = list(set(context.input_walker.get_next_input())) + output_transactions = list(set(context.output_walker.get_next_output())) + + if context.log_transactions: + transaction_logger.info(f"Transactions expanded input direction: {transactions}") + transaction_logger.info(f"Transactions expanded output direction: {output_transactions}") + + + logger.info(f"Total transactions expanded up to now: {summary.expanded_transactions} ({summary.expanded_transactions / (time.time()-start_time):.2f} tx/s). " + f"Expanding {len(transactions)} input direction + {len(output_transactions)} output direction transactions. Depth: {depth}") + + logger.debug(f"TX in common: {len(previous_transactions.intersection(set(transactions)))}") + previous_transactions = set(transactions) + + # All the resume setup should be done by now, so we're effectively back into "normal" processing + context.resumed = False + + kill_queue = Queue() + receive_queue = Queue() + input_thread = Thread(target=parallel_execution, args=(driver, input_thread_function, kill_queue, transactions, receive_queue)) + input_thread.start() + + output_thread = Thread(target=parallel_execution, args=(driver, output_thread_function, kill_queue, output_transactions, receive_queue)) + output_thread.start() + + done_transactions = set() + broken = 0 + while True: + x = receive_queue.get() + + if x is None: + broken += 1 + if broken >= 2: + # this only happens when the thread as finished processing all transactions and it's the only + # way out of the while True loop (except for successfully finding a complete path) + # It has to break twice because it has to break for the output and input thread + break + continue + + txid, is_input, rows = x + if is_input: + context.input_walker.process_input(txid, rows, context.end_addresses) + else: + context.output_walker.process_output(txid, rows) + + if context.log_transactions: + transaction_logger.info(f"Explored {txid}") + + done_transactions.add(txid) + summary.expanded_transactions += 1 + + intersection = context.input_walker.txids.intersection(context.output_walker.txids) + if intersection: + intersect_txid = list(intersection)[0] + logger.info("Found path") + input_path = context.input_walker.get_path(intersect_txid) + logger.info(input_path) + output_path = context.output_walker.get_path(intersect_txid) + logger.info(output_path) + logger.info(path_to_query(input_path, output_path)) + exit(0) + # save progress every 6 hours + if time.time() - last_save > 60*60*6: + logger.info("Saving progress") + context.resumed = True + + # we need to save the current state to avoid re-running all the transactions at current depth + context.previous_transactions = previous_transactions + context.transactions = transactions + context.output_transactions = output_transactions + context.done_transactions = done_transactions + context.curr_depth = depth + + with open(f"progress_{RUN_ID}.pickle", "wb+") as f: + pickle.dump(context, f) + context.resumed = False + last_save = time.time() + + context.input_walker.empty_garbage() + summary.depth = depth + context.curr_depth = depth + finally: + logger.info(f"Exited. Expanded a total of {summary.expanded_transactions} transactions up to depth {context.curr_depth}") + + +def resume_tracking(driver, path: str): + global RUN_ID + with open(pathlib.Path(path).resolve(), "rb") as f: + ctx: Context = pickle.load(f) + + RUN_ID = path.split("_")[1].split(".")[0].strip() + setup_logging() + logger.info(f"Resuming from {RUN_ID}:\nMin amount: {ctx.min_amount}\nDepth: {ctx.curr_depth}->{ctx.max_depth}\n" + f"Log transactions: {ctx.log_transactions}\nIgnore entities: {ctx.ignore_entities}") + track_output(driver, ctx) + +def setup_track_output(driver, start, end, min_amount, max_depth, ignore_entities, log_transactions): + global MIN_AMOUNT + MIN_AMOUNT = min_amount + setup_logging() + logger.info(f"Finding bitcoin trail {end}->{start}. Minimum transaction amount: {min_amount}$") + if ignore_entities: + logger.info("Ignoring paths through entities") + + address_to_outputs = {} + input_walker = InputWalker() + output_walker = OutputWalker() + with driver.session() as session: + logger.info(f"Getting addresses of entity {start}") + try: + int(start) + name = "entity_id" + except: + name = "name" + + result = session.run(""" + MATCH (e:Entity {%s: $entityName})--(a:Address)--(o:Output) + WITH a.address as address, collect(o.txid_n) as o + RETURN address, o + """ % name, entityName=start).values() + + for address, outputs in result: + address_to_outputs[address] = [] + for o in outputs: + address_to_outputs[address].append(o) + input_walker.add_root(o) + logger.info(f"Addresses found: {address_to_outputs.keys()}") + logger.info(f"Getting addresses of entity {end}") + try: + int(end) + name = "entity_id" + except: + name = "name" + + result = session.run(""" + MATCH (e:Entity {%s: $entityName})--(a:Address)--(o:Output)-[:INPUT]->(t:Transaction)<-[:CONTAINS]-(b:Block) + WITH a.address as address, collect([o.txid_n, o.value, t.txid, b.timestamp]) as tuples + RETURN address, tuples + """ % name, entityName=end).values() + + end_addresses = set([]) + for address, tuples in result: + end_addresses.add(address) + address_to_outputs[address] = [] + for txid_n, value, txid, ts in tuples: + if get_average_price(ts) * value < MIN_AMOUNT: + continue + address_to_outputs[address].append(txid_n) + output_walker.process_output('root', [[txid_n, address, txid]]) + + logger.info(f"Addresses found: {list(end_addresses)}") + + previous_transactions = set([]) + ctx = Context(input_walker=input_walker, transactions=[], previous_transactions=set([]), log_transactions=log_transactions, + address_to_outputs=address_to_outputs, end_addresses=end_addresses, curr_depth=0, max_depth=max_depth, + ignore_entities=ignore_entities, resumed=False, done_transactions=set([]), end=end, min_amount=min_amount, + start=start, output_walker=output_walker, output_transactions=[]) + + setup_logging() + track_output(driver, ctx) + +def get_average_price(timestamp): + data = { + "Aug 21": 47_130.4, "Jul 21": 41_553.7, "Jun 21": 35_026.9, "May 21": 37_298.6, + "Apr 21": 57_720.3, "Mar 21": 58_763.7, "Feb 21": 45_164.0, "Jan 21": 33_108.1, + "Dec 20": 28_949.4, "Nov 20": 19_698.1, "Oct 20": 13_797.3, "Sep 20": 10_776.1, + "Aug 20": 11_644.2, "Jul 20": 11_333.4, "Jun 20": 9_135.4, "May 20": 9_454.8, + "Apr 20": 8_629.0, "Mar 20": 6_412.5, "Feb 20": 8_543.7, "Jan 20": 9_349.1, + "Dec 19": 7_196.4, "Nov 19": 7_546.6, "Oct 19": 9_152.6, "Sep 19": 8_284.3, + "Aug 19": 9_594.4, "Jul 19": 10_082.0, "Jun 19": 10_818.6, "May 19": 8_558.3, + "Apr 19": 5_320.8, "Mar 19": 4_102.3, "Feb 19": 3_816.6, "Jan 19": 3_437.2, + "Dec 18": 3_709.4, "Nov 18": 4_039.7, "Oct 18": 6_365.9, "Sep 18": 6_635.2, + } + + given_date = datetime.fromtimestamp(timestamp) + date_format = "%b %y" + closest_date = min(data.keys(), key=lambda x: abs(given_date - datetime.strptime(x, date_format))) + return data[closest_date] + +parser = argparse.ArgumentParser( + description="This binary is used to find the shortest direct bitcoin trail from one entity to another. The entity " + "Can be provided both as entity_id (NOT the neo4j hidden id, the value entity.id), or as a name. " + "By direct trail, we mean it only follows the following two types of trail:" + "(receiver)<-[:USES]<-(:Output)<-[:INPUT]<-..(:Transaction)..<-[:OUTPUT]-(:Output)-[:USES]->(owner)" + "Additionally, it goes through entities, so for each Output, it looks at the associated address and the entity," + "and if there's one, it also follows all the input to the entity addresses\n" + "The parameter --min-amount-dollars can further be used to filter out Outputs that have a value" + "smaller than the min amount. It uses the lower bound of the BTC value for the month of the transaction\n\n" + "Keep in mind it knows which to call based on whether the id can be converted to an integer, so if you provide " + "a name which is actually a number, it will try to get the entity with that entity_id instead of name." +) +parser.add_argument('receiver', help="Entity name or id receiving the bitcoins", nargs="?") +parser.add_argument('owner', help="Entity name or id sending the bitcoins", nargs="?") +parser.add_argument('--resume-path', help='Progress file from which to resume', required=False) +parser.add_argument('--host', default="0.0.0.0", help='Neo4j host') +parser.add_argument('--port', default=7687, help='Neo4j port', type=int) +parser.add_argument('-u', '--username', required=True, help='Neo4j user') +parser.add_argument('-p', '--password', required=True, help='Neo4j password') +parser.add_argument('-d', '--max-depth', required=False, help='Max depth to expand (in transactions)', default=100, type=int) +parser.add_argument('-m', '--min-amount-dollars', required=False, default=1000, type=int, + help="Skip expanding outputs if the associated value is lower than this (in dollars).") +parser.add_argument("--ignore-entities", action="store_true", + help="Do not go through entities along the way.") +parser.add_argument("--log-transactions", action="store_true", + help="Log all transactions explored") + + +if __name__ == "__main__": + args = parser.parse_args() + if (args.receiver is None or args.owner is None) and args.resume_path is None: + print("You must either pass receiver and owner, or a resume path") + exit(1) + + driver = GraphDatabase.driver(f"bolt://{args.host}:{args.port}", + auth=(args.username, args.password), + connection_timeout=3600) + + if args.resume_path: + resume_tracking(driver, args.resume_path) + else: + setup_track_output(driver, args.receiver, args.owner, args.min_amount_dollars, args.max_depth, args.ignore_entities, + args.log_transactions) + diff --git a/scripts/merge-entities/Cargo.toml b/scripts/merge-entities/Cargo.toml new file mode 100644 index 0000000..eb61423 --- /dev/null +++ b/scripts/merge-entities/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "merge_entities" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/scripts/merge-entities/src/main.rs b/scripts/merge-entities/src/main.rs new file mode 100644 index 0000000..2dc69bd --- /dev/null +++ b/scripts/merge-entities/src/main.rs @@ -0,0 +1,146 @@ +use std::collections::HashMap; +use std::env; +use std::error::Error; +use std::fs::File; +use std::io::{BufRead, BufReader, BufWriter, Write}; +use std::path::Path; +use std::collections::HashSet; +use std::time::{Instant, SystemTime, UNIX_EPOCH}; + +struct UnionFind { + pub parent: HashMap, +} + +impl UnionFind { + fn new() -> UnionFind { + UnionFind { + parent: HashMap::new(), + } + } + + fn union(&mut self, x: usize, y: usize) { + let root_x = self.find(x); + let root_y = self.find(y); + if root_x != root_y { + self.parent.insert(root_x, root_y); + } + } + + fn find(&mut self, x: usize) -> usize { + if !self.parent.contains_key(&x) { + self.parent.insert(x, x); + } + + if *self.parent.get(&x).unwrap() != x { + let parent = *self.parent.get(&x).unwrap(); + let found = self.find(parent); + self.parent.insert(x, found); + } + + *self.parent.get(&x).unwrap() + } +} + +fn main() -> Result<(), Box> { + let args: Vec = env::args().collect(); + if args.len() < 3 { + return Err("Please specify the input and output CSV files".into()); + } + + let input_path = Path::new(&args[1]); + let output_path = Path::new(&args[2]); + + // Extract the parent directory of the original path + let entity_path = match output_path.parent() { + None => { + eprintln!("Original path has no parent directory."); + return Err(Box::from("Original path has no parent directory.".to_string())); + } + Some(parent) => parent.join("entity.csv") + }; + + let input_file = File::open(&input_path)?; + let reader = BufReader::new(input_file); + + let mut idx_map: HashMap = HashMap::new(); + let mut uf = UnionFind::new(); + + let tmp_lines_path = format!("/tmp/merge_entities_{}", SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis()); + let tmp_lines_file = File::create(&tmp_lines_path)?; + let mut tmp = BufWriter::new(tmp_lines_file); + + let start_time = Instant::now(); + for (index, line) in reader.lines().enumerate() { + let line = line?; + let parts: Vec<&str> = line.split(',').collect(); + + if parts.len() != 2 { + return Err("Invalid line format".into()); + } + + let idx: usize = parts[0].parse()?; + let str = parts[1].to_string(); + + if let Some(first_idx) = idx_map.get(&str) { + uf.union(*first_idx, idx); + } else { + idx_map.insert(str.clone(), idx); + // lines.push((idx, str)); + write!(tmp, "{},{}\n", idx, str)?; + } + if index>0 && index % 10_000_000 == 0{ + println!("Processed {:?} lines in {:?} seconds", &index, &start_time.elapsed().as_secs()); + } + } + tmp.flush()?; + + let output_file = File::create(&output_path)?; + let mut writer = BufWriter::new(output_file); + + println!("Done processing lines. Writing new file."); + let mut start_write = Instant::now(); + + let tmp_lines_file = File::open(&tmp_lines_path)?; + let tmp_lines_reader = BufReader::new(tmp_lines_file); + + for line in tmp_lines_reader.lines() { + let line = line?; + let parts: Vec<&str> = line.split(",").collect(); + let idx = parts[0].parse()?; + let str = parts[1]; + let new_idx = uf.find(idx); + write!(writer, "{},{}\n", new_idx, str)?; + + if idx > 0 && idx % 10_000_000 == 0 { + println!("Wrote {:?} lines in {:?} seconds", &idx, &start_write.elapsed().as_secs()); + } + } + writer.flush()?; + + // Create a HashSet to store the unique values + let mut unique_entity_idx: HashSet = HashSet::new(); + + // Iterate over the values in the HashMap + println!("Finished merging entities. Getting unique entities. Total time since start: {:?}", &start_time.elapsed().as_secs()); + for &value in uf.parent.values() { + // Insert the value into the HashSet, which automatically handles duplicates + unique_entity_idx.insert(value); + } + + println!("Found a total of {:?} entities", &unique_entity_idx.len()); + + let path: &Path = entity_path.as_ref(); + let entity_file = File::create(path)?; + let mut entity_writer = BufWriter::new(entity_file); + println!("Finished getting unique entities. Writing entities.csv. Total time since start: {:?}", &start_time.elapsed().as_secs()); + start_write = Instant::now(); + for (idx, parent) in unique_entity_idx.iter().enumerate() { + write!(entity_writer, "{}\n", parent)?; + if idx > 0 && idx % 10_000_000 == 0{ + println!("Wrote {:?} lines in {:?} seconds", &idx, &start_write.elapsed().as_secs()); + } + } + entity_writer.flush()?; // Ensure all data is written + + Ok(()) +} diff --git a/setup.py b/setup.py index f7d4ac6..5bd755b 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,8 @@ from __future__ import print_function + +import os +import platform + from setuptools import setup from setuptools.command.test import test as TestCommand import io @@ -19,11 +23,21 @@ def read(*filenames, **kwargs): long_description = read('README.rst') +_compatible_install = [ + 'neo4j>=4', + 'requests>=2.5.0', + 'tqdm~=4.65.0' +] + +if platform.python_implementation() == "PyPy": + print("Skipping install neo4j because of PyPy error") + _compatible_install.pop(0) + class PyTest(TestCommand): def finalize_options(self): TestCommand.finalize_options(self) - self.test_args = [] + self.test_args = ['./tests/'] self.test_suite = True def run_tests(self): @@ -32,6 +46,9 @@ def run_tests(self): sys.exit(errcode) +with open('requirements.txt') as f: + requirements = f.read().splitlines() + setup( # Basic info name='bitcoingraph', @@ -53,16 +70,15 @@ def run_tests(self): 'scripts/bcgraph-compute-entities', 'scripts/bcgraph-synchronize'], platforms='any', - install_requires=['requests>=2.5.0'], - + install_requires=requirements, classifiers=[ - 'Development Status :: 4 - Beta', - 'Environment :: Console', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: MIT License', - 'Operating System :: OS Independent', - 'Programming Language :: Python :: 3', - 'Topic :: Software Development :: Libraries', + 'Development Status :: 4 - Beta', + 'Environment :: Console', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: MIT License', + 'Operating System :: OS Independent', + 'Programming Language :: Python :: 3', + 'Topic :: Software Development :: Libraries', ], # Testing @@ -71,6 +87,8 @@ def run_tests(self): cmdclass={'test': PyTest}, extras_require={ 'testing': ['pytest'], + 'ssh': ['paramiko'], + 'profile': ['line-profiler==4.0.3'] }, # Legal info diff --git a/tests/data/tx_a288fec5559c3f73fd3d93db8e8460562ebfe2fcf04a5114e8d0f2920a6270dc.json b/tests/data/block-100000.json similarity index 76% rename from tests/data/tx_a288fec5559c3f73fd3d93db8e8460562ebfe2fcf04a5114e8d0f2920a6270dc.json rename to tests/data/block-100000.json index 05d1704..268ba3a 100644 --- a/tests/data/tx_a288fec5559c3f73fd3d93db8e8460562ebfe2fcf04a5114e8d0f2920a6270dc.json +++ b/tests/data/block-100000.json @@ -1,45 +1,221 @@ { - "txid": "a288fec5559c3f73fd3d93db8e8460562ebfe2fcf04a5114e8d0f2920a6270dc", - "hash": "a288fec5559c3f73fd3d93db8e8460562ebfe2fcf04a5114e8d0f2920a6270dc", + "hash": "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506", + "confirmations": 100001, + "height": 100000, "version": 1, - "size": 4237, - "vsize": 4237, - "weight": 16948, - "locktime": 0, - "vin": [ + "versionHex": "00000001", + "merkleroot": "f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766", + "time": 1293623863, + "mediantime": 1293622620, + "nonce": 274148111, + "bits": "1b04864c", + "difficulty": 14484.1623612254, + "chainwork": "0000000000000000000000000000000000000000000000000644cb7f5234089e", + "nTx": 4, + "previousblockhash": "000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250", + "nextblockhash": "00000000000080b66c911bd5ba14a74260057311eaeb1982802f7010f1a9f090", + "strippedsize": 957, + "size": 957, + "weight": 3828, + "tx": [ { - "txid": "2a0597e665ac3d1cabeede95cedf907934db7f639e477b3c77b242140d8cf728", - "vout": 0, - "scriptSig": { - "asm": "3045022100f078bd992b1840123b8aebceb15d17cbeab566230ea1282bdb77beb52bf77cc702207bc7a73d1ece4805b466b25556cf362ae1b84caf1e0682cfd3b26fce80cee987[ALL]", - "hex": "483045022100f078bd992b1840123b8aebceb15d17cbeab566230ea1282bdb77beb52bf77cc702207bc7a73d1ece4805b466b25556cf362ae1b84caf1e0682cfd3b26fce80cee98701" - }, - "sequence": 4294967295 - } - ], - "vout": [ + "txid": "8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87", + "hash": "8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87", + "version": 1, + "size": 135, + "vsize": 135, + "weight": 540, + "locktime": 0, + "vin": [ + { + "coinbase": "044c86041b020602", + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 50.0, + "n": 0, + "scriptPubKey": { + "asm": "041b0e8c2567c12536aa13357b79a073dc4444acb83c4ec7a0e2f99dd7457516c5817242da796924ca4e99947d087fedf9ce467cb9f7c6287078f801df276fdf84 OP_CHECKSIG", + "desc": "pk(041b0e8c2567c12536aa13357b79a073dc4444acb83c4ec7a0e2f99dd7457516c5817242da796924ca4e99947d087fedf9ce467cb9f7c6287078f801df276fdf84)#40d2kraw", + "hex": "41041b0e8c2567c12536aa13357b79a073dc4444acb83c4ec7a0e2f99dd7457516c5817242da796924ca4e99947d087fedf9ce467cb9f7c6287078f801df276fdf84ac", + "type": "pubkey" + } + } + ], + "hex": "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff08044c86041b020602ffffffff0100f2052a010000004341041b0e8c2567c12536aa13357b79a073dc4444acb83c4ec7a0e2f99dd7457516c5817242da796924ca4e99947d087fedf9ce467cb9f7c6287078f801df276fdf84ac00000000" + }, + { + "txid": "fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4", + "hash": "fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4", + "version": 1, + "size": 259, + "vsize": 259, + "weight": 1036, + "locktime": 0, + "vin": [ + { + "txid": "87a157f3fd88ac7907c05fc55e271dc4acdc5605d187d646604ca8c0e9382e03", + "vout": 0, + "scriptSig": { + "asm": "3046022100c352d3dd993a981beba4a63ad15c209275ca9470abfcd57da93b58e4eb5dce82022100840792bc1f456062819f15d33ee7055cf7b5ee1af1ebcc6028d9cdb1c3af7748[ALL] 04f46db5e9d61a9dc27b8d64ad23e7383a4e6ca164593c2527c038c0857eb67ee8e825dca65046b82c9331586c82e0fd1f633f25f87c161bc6f8a630121df2b3d3", + "hex": "493046022100c352d3dd993a981beba4a63ad15c209275ca9470abfcd57da93b58e4eb5dce82022100840792bc1f456062819f15d33ee7055cf7b5ee1af1ebcc6028d9cdb1c3af7748014104f46db5e9d61a9dc27b8d64ad23e7383a4e6ca164593c2527c038c0857eb67ee8e825dca65046b82c9331586c82e0fd1f633f25f87c161bc6f8a630121df2b3d3" + }, + "prevout": { + "generated": false, + "height": 99059, + "value": 50.0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 71d7dd96d9edda09180fe9d57a477b5acc9cad11 OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1BNwxHGaFbeUBitpjy2AsKpJ29Ybxntqvb)#jnp2wyds", + "hex": "76a91471d7dd96d9edda09180fe9d57a477b5acc9cad1188ac", + "address": "1BNwxHGaFbeUBitpjy2AsKpJ29Ybxntqvb", + "type": "pubkeyhash" + } + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 5.56, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 c398efa9c392ba6013c5e04ee729755ef7f58b32 OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1JqDybm2nWTENrHvMyafbSXXtTk5Uv5QAn)#70tf4ktg", + "hex": "76a914c398efa9c392ba6013c5e04ee729755ef7f58b3288ac", + "address": "1JqDybm2nWTENrHvMyafbSXXtTk5Uv5QAn", + "type": "pubkeyhash" + } + }, + { + "value": 44.44, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 948c765a6914d43f2a7ac177da2c2f6b52de3d7c OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1EYTGtG4LnFfiMvjJdsU7GMGCQvsRSjYhx)#t40fmm8a", + "hex": "76a914948c765a6914d43f2a7ac177da2c2f6b52de3d7c88ac", + "address": "1EYTGtG4LnFfiMvjJdsU7GMGCQvsRSjYhx", + "type": "pubkeyhash" + } + } + ], + "fee": 0.0, + "hex": "0100000001032e38e9c0a84c6046d687d10556dcacc41d275ec55fc00779ac88fdf357a187000000008c493046022100c352d3dd993a981beba4a63ad15c209275ca9470abfcd57da93b58e4eb5dce82022100840792bc1f456062819f15d33ee7055cf7b5ee1af1ebcc6028d9cdb1c3af7748014104f46db5e9d61a9dc27b8d64ad23e7383a4e6ca164593c2527c038c0857eb67ee8e825dca65046b82c9331586c82e0fd1f633f25f87c161bc6f8a630121df2b3d3ffffffff0200e32321000000001976a914c398efa9c392ba6013c5e04ee729755ef7f58b3288ac000fe208010000001976a914948c765a6914d43f2a7ac177da2c2f6b52de3d7c88ac00000000" + }, { - "value": 0.02, - "n": 0, - "scriptPubKey": { - "asm": "0469b7eaf1cca8a7c8592ad49313b4cb6474a845604456d48b4b252904e1d61ceda95ac987ad163e957bdbd2da2736861fbfad93dbf8e0a218308a49d94ab9a077 OP_CHECKSIG", - "hex": "410469b7eaf1cca8a7c8592ad49313b4cb6474a845604456d48b4b252904e1d61ceda95ac987ad163e957bdbd2da2736861fbfad93dbf8e0a218308a49d94ab9a077ac", - "type": "pubkey" - } + "txid": "6359f0868171b1d194cbee1af2f16ea598ae8fad666d9b012c8ed2b79a236ec4", + "hash": "6359f0868171b1d194cbee1af2f16ea598ae8fad666d9b012c8ed2b79a236ec4", + "version": 1, + "size": 257, + "vsize": 257, + "weight": 1028, + "locktime": 0, + "vin": [ + { + "txid": "cf4e2978d0611ce46592e02d7e7daf8627a316ab69759a9f3df109a7f2bf3ec3", + "vout": 1, + "scriptSig": { + "asm": "30440220032d30df5ee6f57fa46cddb5eb8d0d9fe8de6b342d27942ae90a3231e0ba333e02203deee8060fdc70230a7f5b4ad7d7bc3e628cbe219a886b84269eaeb81e26b4fe[ALL] 04ae31c31bf91278d99b8377a35bbce5b27d9fff15456839e919453fc7b3f721f0ba403ff96c9deeb680e5fd341c0fc3a7b90da4631ee39560639db462e9cb850f", + "hex": "4730440220032d30df5ee6f57fa46cddb5eb8d0d9fe8de6b342d27942ae90a3231e0ba333e02203deee8060fdc70230a7f5b4ad7d7bc3e628cbe219a886b84269eaeb81e26b4fe014104ae31c31bf91278d99b8377a35bbce5b27d9fff15456839e919453fc7b3f721f0ba403ff96c9deeb680e5fd341c0fc3a7b90da4631ee39560639db462e9cb850f" + }, + "prevout": { + "generated": false, + "height": 97003, + "value": 3.0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 35fbee6a3bf8d99f17724ec54787567393a8a6b1 OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(15vScfMHNrXN4QvWe54q5hwfVoYwG79CS1)#8n0e4883", + "hex": "76a91435fbee6a3bf8d99f17724ec54787567393a8a6b188ac", + "address": "15vScfMHNrXN4QvWe54q5hwfVoYwG79CS1", + "type": "pubkeyhash" + } + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.01, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 b0dcbf97eabf4404e31d952477ce822dadbe7e10 OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1H8ANdafjpqYntniT3Ddxh4xPBMCSz33pj)#ejxdpym6", + "hex": "76a914b0dcbf97eabf4404e31d952477ce822dadbe7e1088ac", + "address": "1H8ANdafjpqYntniT3Ddxh4xPBMCSz33pj", + "type": "pubkeyhash" + } + }, + { + "value": 2.99, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 6b1281eec25ab4e1e0793ff4e08ab1abb3409cd9 OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1Am9UTGfdnxabvcywYG2hvzr6qK8T3oUZT)#te23gwt4", + "hex": "76a9146b1281eec25ab4e1e0793ff4e08ab1abb3409cd988ac", + "address": "1Am9UTGfdnxabvcywYG2hvzr6qK8T3oUZT", + "type": "pubkeyhash" + } + } + ], + "fee": 0.0, + "hex": "0100000001c33ebff2a709f13d9f9a7569ab16a32786af7d7e2de09265e41c61d078294ecf010000008a4730440220032d30df5ee6f57fa46cddb5eb8d0d9fe8de6b342d27942ae90a3231e0ba333e02203deee8060fdc70230a7f5b4ad7d7bc3e628cbe219a886b84269eaeb81e26b4fe014104ae31c31bf91278d99b8377a35bbce5b27d9fff15456839e919453fc7b3f721f0ba403ff96c9deeb680e5fd341c0fc3a7b90da4631ee39560639db462e9cb850fffffffff0240420f00000000001976a914b0dcbf97eabf4404e31d952477ce822dadbe7e1088acc060d211000000001976a9146b1281eec25ab4e1e0793ff4e08ab1abb3409cd988ac00000000" }, { - "value": 0.01, - "n": 1, - "scriptPubKey": { - "asm": "OP_DUP OP_HASH160 913ce5a92daf975d2b349ce975057b19e03ad1b2 OP_EQUALVERIFY OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG", - "hex": "76a914913ce5a92daf975d2b349ce975057b19e03ad1b288acacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac", - "type": "nonstandard" - } + "txid": "a288fec5559c3f73fd3d93db8e8460562ebfe2fcf04a5114e8d0f2920a6270dc", + "hash": "a288fec5559c3f73fd3d93db8e8460562ebfe2fcf04a5114e8d0f2920a6270dc", + "version": 1, + "size": 4237, + "vsize": 4237, + "weight": 16948, + "locktime": 0, + "vin": [ + { + "txid": "2a0597e665ac3d1cabeede95cedf907934db7f639e477b3c77b242140d8cf728", + "vout": 0, + "scriptSig": { + "asm": "3045022100f078bd992b1840123b8aebceb15d17cbeab566230ea1282bdb77beb52bf77cc702207bc7a73d1ece4805b466b25556cf362ae1b84caf1e0682cfd3b26fce80cee987[ALL]", + "hex": "483045022100f078bd992b1840123b8aebceb15d17cbeab566230ea1282bdb77beb52bf77cc702207bc7a73d1ece4805b466b25556cf362ae1b84caf1e0682cfd3b26fce80cee98701" + }, + "prevout": { + "generated": false, + "height": 71036, + "value": 0.03, + "scriptPubKey": { + "asm": "04660ec34c94c2776384c7b90746d5d33fa2ccad62e4cf19a1f366a4230539b5d081703652247bee91c9a565a55852b82a3e1068bdd7e670e2268aa4d36071a773 OP_CHECKSIG", + "desc": "pk(04660ec34c94c2776384c7b90746d5d33fa2ccad62e4cf19a1f366a4230539b5d081703652247bee91c9a565a55852b82a3e1068bdd7e670e2268aa4d36071a773)#t0n5pfmg", + "hex": "4104660ec34c94c2776384c7b90746d5d33fa2ccad62e4cf19a1f366a4230539b5d081703652247bee91c9a565a55852b82a3e1068bdd7e670e2268aa4d36071a773ac", + "type": "pubkey" + } + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.02, + "n": 0, + "scriptPubKey": { + "asm": "0469b7eaf1cca8a7c8592ad49313b4cb6474a845604456d48b4b252904e1d61ceda95ac987ad163e957bdbd2da2736861fbfad93dbf8e0a218308a49d94ab9a077 OP_CHECKSIG", + "desc": "pk(0469b7eaf1cca8a7c8592ad49313b4cb6474a845604456d48b4b252904e1d61ceda95ac987ad163e957bdbd2da2736861fbfad93dbf8e0a218308a49d94ab9a077)#j5crek3c", + "hex": "410469b7eaf1cca8a7c8592ad49313b4cb6474a845604456d48b4b252904e1d61ceda95ac987ad163e957bdbd2da2736861fbfad93dbf8e0a218308a49d94ab9a077ac", + "type": "pubkey" + } + }, + { + "value": 0.01, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 913ce5a92daf975d2b349ce975057b19e03ad1b2 OP_EQUALVERIFY OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG OP_CHECKSIG", + "desc": "raw(76a914913ce5a92daf975d2b349ce975057b19e03ad1b288acacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac)#ad8xy8mq", + "hex": "76a914913ce5a92daf975d2b349ce975057b19e03ad1b288acacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac", + "type": "nonstandard" + } + } + ], + "fee": 0.0, + "hex": "010000000128f78c0d1442b2773c7b479e637fdb347990dfce95deeeab1c3dac65e697052a0000000049483045022100f078bd992b1840123b8aebceb15d17cbeab566230ea1282bdb77beb52bf77cc702207bc7a73d1ece4805b466b25556cf362ae1b84caf1e0682cfd3b26fce80cee98701ffffffff0280841e000000000043410469b7eaf1cca8a7c8592ad49313b4cb6474a845604456d48b4b252904e1d61ceda95ac987ad163e957bdbd2da2736861fbfad93dbf8e0a218308a49d94ab9a077ac40420f0000000000fdba0f76a914913ce5a92daf975d2b349ce975057b19e03ad1b288acacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac00000000" } - ], - "hex": "010000000128f78c0d1442b2773c7b479e637fdb347990dfce95deeeab1c3dac65e697052a0000000049483045022100f078bd992b1840123b8aebceb15d17cbeab566230ea1282bdb77beb52bf77cc702207bc7a73d1ece4805b466b25556cf362ae1b84caf1e0682cfd3b26fce80cee98701ffffffff0280841e000000000043410469b7eaf1cca8a7c8592ad49313b4cb6474a845604456d48b4b252904e1d61ceda95ac987ad163e957bdbd2da2736861fbfad93dbf8e0a218308a49d94ab9a077ac40420f0000000000fdba0f76a914913ce5a92daf975d2b349ce975057b19e03ad1b288acacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacac00000000", - "blockhash": "00000000000997f9fd2fe1ee376293ef8c42ad09193a5d2086dddf8e5c426b56", - "confirmations": 169807, - "time": 1280437709, - "blocktime": 1280437709 + ] } \ No newline at end of file diff --git a/tests/data/block-100001.json b/tests/data/block-100001.json new file mode 100644 index 0000000..5340099 --- /dev/null +++ b/tests/data/block-100001.json @@ -0,0 +1,711 @@ +{ + "hash": "00000000000080b66c911bd5ba14a74260057311eaeb1982802f7010f1a9f090", + "confirmations": 100000, + "height": 100001, + "version": 1, + "versionHex": "00000001", + "merkleroot": "7fe79307aeb300d910d9c4bec5bacb4c7e114c7dfd6789e19f3a733debb3bb6a", + "time": 1293624404, + "mediantime": 1293623177, + "nonce": 2613872960, + "bits": "1b04864c", + "difficulty": 14484.1623612254, + "chainwork": "00000000000000000000000000000000000000000000000006450413b458ec1c", + "nTx": 12, + "previousblockhash": "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506", + "nextblockhash": null, + "strippedsize": 3308, + "size": 3308, + "weight": 13232, + "tx": [ + { + "txid": "bb28a1a5b3a02e7657a81c38355d56c6f05e80b9219432e3352ddcfc3cb6304c", + "hash": "bb28a1a5b3a02e7657a81c38355d56c6f05e80b9219432e3352ddcfc3cb6304c", + "version": 1, + "size": 134, + "vsize": 134, + "weight": 536, + "locktime": 0, + "vin": [ + { + "coinbase": "044c86041b010d", + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 50.0, + "n": 0, + "scriptPubKey": { + "asm": "04b27f7e9475ccf5d9a431cb86d665b8302c140144ec2397fce792f4a4e7765fecf8128534eaa71df04f93c74676ae8279195128a1506ebf7379d23dab8fca0f63 OP_CHECKSIG", + "desc": "pk(04b27f7e9475ccf5d9a431cb86d665b8302c140144ec2397fce792f4a4e7765fecf8128534eaa71df04f93c74676ae8279195128a1506ebf7379d23dab8fca0f63)#tff0erdy", + "hex": "4104b27f7e9475ccf5d9a431cb86d665b8302c140144ec2397fce792f4a4e7765fecf8128534eaa71df04f93c74676ae8279195128a1506ebf7379d23dab8fca0f63ac", + "type": "pubkey" + } + } + ], + "hex": "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff07044c86041b010dffffffff0100f2052a01000000434104b27f7e9475ccf5d9a431cb86d665b8302c140144ec2397fce792f4a4e7765fecf8128534eaa71df04f93c74676ae8279195128a1506ebf7379d23dab8fca0f63ac00000000" + }, + { + "txid": "fbde5d03b027d2b9ba4cf5d4fecab9a99864df2637b25ea4cbcb1796ff6550ca", + "hash": "fbde5d03b027d2b9ba4cf5d4fecab9a99864df2637b25ea4cbcb1796ff6550ca", + "version": 1, + "size": 258, + "vsize": 258, + "weight": 1032, + "locktime": 0, + "vin": [ + { + "txid": "bb28a1a5b3a02e7657a81c38355d56c6f05e80b9219432e3352ddcfc3cb6304c", + "vout": 0, + "scriptSig": { + "asm": "3045022100f0519bdc9282ff476da1323b8ef7ffe33f495c1a8d52cc522b437022d83f6a230220159b61d197fbae01b4a66622a23bc3f1def65d5fa24efd5c26fa872f3a246b8e[ALL] 04839f9023296a1fabb133140128ca2709f6818c7d099491690bd8ac0fd55279def6a2ceb6ab7b5e4a71889b6e739f09509565eec789e86886f6f936fa42097ade", + "hex": "483045022100f0519bdc9282ff476da1323b8ef7ffe33f495c1a8d52cc522b437022d83f6a230220159b61d197fbae01b4a66622a23bc3f1def65d5fa24efd5c26fa872f3a246b8e014104839f9023296a1fabb133140128ca2709f6818c7d099491690bd8ac0fd55279def6a2ceb6ab7b5e4a71889b6e739f09509565eec789e86886f6f936fa42097ade" + }, + "prevout": { + "generated": false, + "height": 100001, + "value": 50.0, + "scriptPubKey": { + "asm": "04b27f7e9475ccf5d9a431cb86d665b8302c140144ec2397fce792f4a4e7765fecf8128534eaa71df04f93c74676ae8279195128a1506ebf7379d23dab8fca0f63 OP_CHECKSIG", + "desc": "pk(04b27f7e9475ccf5d9a431cb86d665b8302c140144ec2397fce792f4a4e7765fecf8128534eaa71df04f93c74676ae8279195128a1506ebf7379d23dab8fca0f63)#tff0erdy", + "hex": "4104b27f7e9475ccf5d9a431cb86d665b8302c140144ec2397fce792f4a4e7765fecf8128534eaa71df04f93c74676ae8279195128a1506ebf7379d23dab8fca0f63ac", + "type": "pubkey" + } + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 44.44, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 948c765a6914d43f2a7ac177da2c2f6b52de3d7c OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1EYTGtG4LnFfiMvjJdsU7GMGCQvsRSjYhx)#t40fmm8a", + "hex": "76a914948c765a6914d43f2a7ac177da2c2f6b52de3d7c88ac", + "address": "1EYTGtG4LnFfiMvjJdsU7GMGCQvsRSjYhx", + "type": "pubkeyhash" + } + }, + { + "value": 5.56, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 0c34f4e29ab5a615d5ea28d4817f12b137d62ed5 OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(127YYnp1jvgAX3vCB22WUUsuyTYfAeSQHh)#g08f2zfh", + "hex": "76a9140c34f4e29ab5a615d5ea28d4817f12b137d62ed588ac", + "address": "127YYnp1jvgAX3vCB22WUUsuyTYfAeSQHh", + "type": "pubkeyhash" + } + } + ], + "fee": 0.0, + "hex": "0100000001d992e5a888a86d4c7a6a69167a4728ee69497509740fc5f456a24528c340219a000000008b483045022100f0519bdc9282ff476da1323b8ef7ffe33f495c1a8d52cc522b437022d83f6a230220159b61d197fbae01b4a66622a23bc3f1def65d5fa24efd5c26fa872f3a246b8e014104839f9023296a1fabb133140128ca2709f6818c7d099491690bd8ac0fd55279def6a2ceb6ab7b5e4a71889b6e739f09509565eec789e86886f6f936fa42097adeffffffff02000fe208010000001976a914948c765a6914d43f2a7ac177da2c2f6b52de3d7c88ac00e32321000000001976a9140c34f4e29ab5a615d5ea28d4817f12b137d62ed588ac00000000" + }, + { + "txid": "8131ffb0a2c945ecaf9b9063e59558784f9c3a74741ce6ae2a18d0571dac15bb", + "hash": "8131ffb0a2c945ecaf9b9063e59558784f9c3a74741ce6ae2a18d0571dac15bb", + "version": 1, + "size": 647, + "vsize": 647, + "weight": 2588, + "locktime": 0, + "vin": [ + { + "coinbase": "044c860414010d", + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 250.0, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 366a27645806e817a6cd40bc869bdad92fe55091 OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(15xif4SjXiFi3NDEsmMZCfTdE9jvvVQrjU)#08xy7akd", + "hex": "76a914366a27645806e817a6cd40bc869bdad92fe5509188ac", + "address": "15xif4SjXiFi3NDEsmMZCfTdE9jvvVQrjU", + "type": "pubkeyhash" + } + }, + { + "value": 0.01, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 ee8bd501094a7d5ca318da2506de35e1cb025ddc OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1NkKLMgbSjXrT7oHagnGmYFhXAWXjJsKCj)#kcy7cwlk", + "hex": "76a914ee8bd501094a7d5ca318da2506de35e1cb025ddc88ac", + "address": "1NkKLMgbSjXrT7oHagnGmYFhXAWXjJsKCj", + "type": "pubkeyhash" + } + } + ], + "fee": 0.0, + "hex": "01000000059daf0abe7a92618546a9dbcfd65869b6178c66ec21ccfda878c1175979cfd9ef000000004a493046022100c2f7f25be5de6ce88ac3c1a519514379e91f39b31ddff279a3db0b1a229b708b022100b29efbdbd9837cc6a6c7318aa4900ed7e4d65662c34d1622a2035a3a5534a99a01ffffffffd516330ebdf075948da56db13d22632a4fb941122df2884397dda45d451acefb0000000048473044022051243debe6d4f2b433bee0cee78c5c4073ead0e3bde54296dbed6176e128659c022044417bfe16f44eb7b6eb0cdf077b9ce972a332e15395c09ca5e4f602958d266101ffffffffe1f5aa33961227b3c344e57179417ce01b7ccd421117fe2336289b70489883f900000000484730440220593252bb992ce3c85baf28d6e3aa32065816271d2c822398fe7ee28a856bc943022066d429dd5025d3c86fd8fd8a58e183a844bd94aa312cefe00388f57c85b0ca3201ffffffffe207e83718129505e6a7484831442f668164ae659fddb82e9e5421a081fb90d50000000049483045022067cf27eb733e5bcae412a586b25a74417c237161a084167c2a0b439abfebdcb2022100efcc6baa6824b4c5205aa967e0b76d31abf89e738d4b6b014e788c9a8cccaf0c01ffffffffe23b8d9d80a9e9d977fab3c94dbe37befee63822443c3ec5ae5a713ede66c3940000000049483045022020f2eb35036666b1debe0d1d2e77a36d5d9c4e96c1dba23f5100f193dbf524790221008ce79bc1321fb4357c6daee818038d41544749127751726e46b2b320c8b565a201ffffffff0200ba1dd2050000001976a914366a27645806e817a6cd40bc869bdad92fe5509188ac40420f00000000001976a914ee8bd501094a7d5ca318da2506de35e1cb025ddc88ac00000000" + }, + { + "txid": "d6c7cb254aa7a5fd446e8b48c307890a2d4e426da8ad2e1191cc1d8bbe0677d7", + "hash": "d6c7cb254aa7a5fd446e8b48c307890a2d4e426da8ad2e1191cc1d8bbe0677d7", + "version": 1, + "size": 193, + "vsize": 193, + "weight": 772, + "locktime": 0, + "vin": [ + { + "txid": "9c456c35371cef98ca0f68d88817a7e5813f51da773002bb1d4b9b0cdcd2ba0a", + "vout": 0, + "scriptSig": { + "asm": "3046022100a894e521c87b3dbe23007079db4ac2896e9e791f8b57317ba6c0d99a7becd27a022100bc40981393eafeb33e89079f857c728701a9af4523c3f857cd96a500f2407809[ALL]", + "hex": "493046022100a894e521c87b3dbe23007079db4ac2896e9e791f8b57317ba6c0d99a7becd27a022100bc40981393eafeb33e89079f857c728701a9af4523c3f857cd96a500f240780901" + }, + "prevout": { + "generated": true, + "height": 99875, + "value": 50.0, + "scriptPubKey": { + "asm": "04c51fa879c5f452fa60a7519e7cf650b9f36c0e7288076d7f8668dc094e55c2e174bfe62c7ff20d62228621b2404137e490ab8d0e1d0a4de219256ddd64b63dee OP_CHECKSIG", + "desc": "pk(04c51fa879c5f452fa60a7519e7cf650b9f36c0e7288076d7f8668dc094e55c2e174bfe62c7ff20d62228621b2404137e490ab8d0e1d0a4de219256ddd64b63dee)#3d9xm7vp", + "hex": "4104c51fa879c5f452fa60a7519e7cf650b9f36c0e7288076d7f8668dc094e55c2e174bfe62c7ff20d62228621b2404137e490ab8d0e1d0a4de219256ddd64b63deeac", + "type": "pubkey" + } + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 48.81, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 d28f9cefb58c1f7a5f97aa6b79047585f58fbd43 OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1LCLwhBgimzwiS8SyEVmWrm2JjM8SSdF7e)#s93su3p3", + "hex": "76a914d28f9cefb58c1f7a5f97aa6b79047585f58fbd4388ac", + "address": "1LCLwhBgimzwiS8SyEVmWrm2JjM8SSdF7e", + "type": "pubkeyhash" + } + }, + { + "value": 1.19, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 2229481696e417aa5f51ad751d8cd4c6a669e4fe OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(147dRpRoYQxpf5WGnz7dipCcavtANRRfjt)#84lu946g", + "hex": "76a9142229481696e417aa5f51ad751d8cd4c6a669e4fe88ac", + "address": "147dRpRoYQxpf5WGnz7dipCcavtANRRfjt", + "type": "pubkeyhash" + } + } + ], + "fee": 0.0, + "hex": "01000000010abad2dc0c9b4b1dbb023077da513f81e5a71788d8680fca98ef1c37356c459c000000004a493046022100a894e521c87b3dbe23007079db4ac2896e9e791f8b57317ba6c0d99a7becd27a022100bc40981393eafeb33e89079f857c728701a9af4523c3f857cd96a500f240780901ffffffff024026ee22010000001976a914d28f9cefb58c1f7a5f97aa6b79047585f58fbd4388acc0cb1707000000001976a9142229481696e417aa5f51ad751d8cd4c6a669e4fe88ac00000000" + }, + { + "txid": "ce29e5407f5e4c9ad581c337a639f3041b24220d5aa60370d96a39335538810b", + "hash": "ce29e5407f5e4c9ad581c337a639f3041b24220d5aa60370d96a39335538810b", + "version": 1, + "size": 191, + "vsize": 191, + "weight": 764, + "locktime": 0, + "vin": [ + { + "txid": "0d41a92e252e68c32443fc428016c081cb76069356b04dd8180b9e64b3896df6", + "vout": 0, + "scriptSig": { + "asm": "3044022038e0b55b37c9253bfeda59c76c0134530f91fb586d6eb21738a77a984f370a44022048d4d477aaf97ef9c8275bbc5cb19b9c8a0e9b1f9fdafdd39bc85bf6c2f04a4d[ALL]", + "hex": "473044022038e0b55b37c9253bfeda59c76c0134530f91fb586d6eb21738a77a984f370a44022048d4d477aaf97ef9c8275bbc5cb19b9c8a0e9b1f9fdafdd39bc85bf6c2f04a4d01" + }, + "prevout": { + "generated": true, + "height": 99881, + "value": 50.01, + "scriptPubKey": { + "asm": "041e0fda51a022022365806821060ff21319758a1e853dbf8aad20c7af2820b01948bb86e98b22e00b70667972c3fbdf3bb5c981ba1d5bc540d7961504bf001eb3 OP_CHECKSIG", + "desc": "pk(041e0fda51a022022365806821060ff21319758a1e853dbf8aad20c7af2820b01948bb86e98b22e00b70667972c3fbdf3bb5c981ba1d5bc540d7961504bf001eb3)#te5ac523", + "hex": "41041e0fda51a022022365806821060ff21319758a1e853dbf8aad20c7af2820b01948bb86e98b22e00b70667972c3fbdf3bb5c981ba1d5bc540d7961504bf001eb3ac", + "type": "pubkey" + } + }, + "sequence": 4294967295 + }, + { + "txid": "6359f0868171b1d194cbee1af2f16ea598ae8fad666d9b012c8ed2b79a236ec4", + "vout": 1, + "scriptSig": { + "asm": "3044022038e0b55b37c9253bfeda59c76c0134530f91fb586d6eb21738a77a984f370a44022048d4d477aaf97ef9c8275bbc5cb19b9c8a0e9b1f9fdafdd39bc85bf6c2f04a4d[ALL]", + "hex": "473044022038e0b55b37c9253bfeda59c76c0134530f91fb586d6eb21738a77a984f370a44022048d4d477aaf97ef9c8275bbc5cb19b9c8a0e9b1f9fdafdd39bc85bf6c2f04a4d01" + }, + "prevout": { + "generated": true, + "height": 100000, + "value": 2.99, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 6b1281eec25ab4e1e0793ff4e08ab1abb3409cd9 OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1Am9UTGfdnxabvcywYG2hvzr6qK8T3oUZT)#te23gwt4", + "hex": "76a9146b1281eec25ab4e1e0793ff4e08ab1abb3409cd988ac", + "address": "1Am9UTGfdnxabvcywYG2hvzr6qK8T3oUZT", + "type": "pubkeyhash" + } + }, + "sequence": 4294967295 + }, + { + "txid": "110ed92f558a1e3a94976ddea5c32f030670b5c58c3cc4d857ac14d7a1547a90", + "vout": 0, + "scriptSig": { + "asm": "3044022038e0b55b37c9253bfeda59c76c0134530f91fb586d6eb21738a77a984f370a44022048d4d477aaf97ef9c8275bbc5cb19b9c8a0e9b1f9fdafdd39bc85bf6c2f04a4d[ALL]", + "hex": "473044022038e0b55b37c9253bfeda59c76c0134530f91fb586d6eb21738a77a984f370a44022048d4d477aaf97ef9c8275bbc5cb19b9c8a0e9b1f9fdafdd39bc85bf6c2f04a4d01" + }, + "prevout": { + "generated": true, + "height": 99999, + "value": 50.0, + "n": 0, + "scriptPubKey": { + "asm": "04d190840cfdae05af3d2febca52b0466b6efb02b44036a5d0d70659a53f7b84b736c5a05ed81e90af70985d59ffb3d1b91364f70b4d2b3b7553e177b1ceaff322 OP_CHECKSIG", + "desc": "pk(04d190840cfdae05af3d2febca52b0466b6efb02b44036a5d0d70659a53f7b84b736c5a05ed81e90af70985d59ffb3d1b91364f70b4d2b3b7553e177b1ceaff322)#uhumlu8n", + "hex": "4104d190840cfdae05af3d2febca52b0466b6efb02b44036a5d0d70659a53f7b84b736c5a05ed81e90af70985d59ffb3d1b91364f70b4d2b3b7553e177b1ceaff322ac", + "type": "pubkey" + } + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 48.93, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 955f70ac8792b48b7bd52b15413bd8500ecf32c8 OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1Ecp1t1JPqoAXLeQqo5qUusCLriu3foeff)#r0rukrhq", + "hex": "76a914955f70ac8792b48b7bd52b15413bd8500ecf32c888ac", + "address": "1Ecp1t1JPqoAXLeQqo5qUusCLriu3foeff", + "type": "pubkeyhash" + } + }, + { + "value": 1.08, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 86116d15f3dbb23a2b58346f36e6ec2d867eba2b OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1DDtRVbeUaoVzBtDVAjBwwT9Y8dcVGj3fB)#tsq5a5gt", + "hex": "76a91486116d15f3dbb23a2b58346f36e6ec2d867eba2b88ac", + "address": "1DDtRVbeUaoVzBtDVAjBwwT9Y8dcVGj3fB", + "type": "pubkeyhash" + } + } + ], + "fee": 0.0, + "hex": "0100000001f66d89b3649e0b18d84db056930676cb81c0168042fc4324c3682e252ea9410d0000000048473044022038e0b55b37c9253bfeda59c76c0134530f91fb586d6eb21738a77a984f370a44022048d4d477aaf97ef9c8275bbc5cb19b9c8a0e9b1f9fdafdd39bc85bf6c2f04a4d01ffffffff024041a523010000001976a914955f70ac8792b48b7bd52b15413bd8500ecf32c888ac00f36f06000000001976a91486116d15f3dbb23a2b58346f36e6ec2d867eba2b88ac00000000" + }, + { + "txid": "45a38677e1be28bd38b51bc1a1c0280055375cdf54472e04c590a989ead82515", + "hash": "45a38677e1be28bd38b51bc1a1c0280055375cdf54472e04c590a989ead82515", + "version": 1, + "size": 258, + "vsize": 258, + "weight": 1032, + "locktime": 0, + "vin": [ + { + "txid": "4e75ee9291fb515f3c40373d2c5fbd3798ba3165dde82b4f6a44634f9884c326", + "vout": 1, + "scriptSig": { + "asm": "304502210083af8324456f052ff1b2597ff0e6a8cce8b006e379a410cf781be7874a2691c2022072259e2f7292960dea0ffc361bbad0b861f719beb8550476f22ce0f82c023449[ALL] 04f3ed46a81cba02af0593e8572a9130adb0d348b538c829ccaaf8e6075b78439b2746a76891ce7ba71abbcbb7ca76e8a220782738a6789562827c1065b0ce911d", + "hex": "48304502210083af8324456f052ff1b2597ff0e6a8cce8b006e379a410cf781be7874a2691c2022072259e2f7292960dea0ffc361bbad0b861f719beb8550476f22ce0f82c023449014104f3ed46a81cba02af0593e8572a9130adb0d348b538c829ccaaf8e6075b78439b2746a76891ce7ba71abbcbb7ca76e8a220782738a6789562827c1065b0ce911d" + }, + "prevout": { + "generated": false, + "height": 99972, + "value": 48.63, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 c45fd674163ff1b104cf278f7abb1dd4544fdc69 OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1JuLFX8dwdFEoSxEkf831aWtZoU62pB6uL)#g5fl279v", + "hex": "76a914c45fd674163ff1b104cf278f7abb1dd4544fdc6988ac", + "address": "1JuLFX8dwdFEoSxEkf831aWtZoU62pB6uL", + "type": "pubkeyhash" + } + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 1.27, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 63d4dd1b29d95ed601512b487bfc1c49d84d0579 OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1A6ru2AYP9gMBpMEw63fwLqXNJ75efaBiY)#pr99jlt9", + "hex": "76a91463d4dd1b29d95ed601512b487bfc1c49d84d057988ac", + "address": "1A6ru2AYP9gMBpMEw63fwLqXNJ75efaBiY", + "type": "pubkeyhash" + } + }, + { + "value": 47.36, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 65746bef92511df7b34abf71c162efb7ae353de3 OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1AFSiVVChPx1oLHXFwqatb3o7GnJzscavZ)#wp3llkfs", + "hex": "76a91465746bef92511df7b34abf71c162efb7ae353de388ac", + "address": "1AFSiVVChPx1oLHXFwqatb3o7GnJzscavZ", + "type": "pubkeyhash" + } + } + ], + "fee": 0.0, + "hex": "010000000126c384984f63446a4f2be8dd6531ba9837bd5f2c3d37403c5f51fb9192ee754e010000008b48304502210083af8324456f052ff1b2597ff0e6a8cce8b006e379a410cf781be7874a2691c2022072259e2f7292960dea0ffc361bbad0b861f719beb8550476f22ce0f82c023449014104f3ed46a81cba02af0593e8572a9130adb0d348b538c829ccaaf8e6075b78439b2746a76891ce7ba71abbcbb7ca76e8a220782738a6789562827c1065b0ce911dffffffff02c0dd9107000000001976a91463d4dd1b29d95ed601512b487bfc1c49d84d057988ac00a0491a010000001976a91465746bef92511df7b34abf71c162efb7ae353de388ac00000000" + }, + { + "txid": "c5abc61566dbb1c4bce5e1fda7b66bed22eb2130cea4b721690bc1488465abc9", + "hash": "c5abc61566dbb1c4bce5e1fda7b66bed22eb2130cea4b721690bc1488465abc9", + "version": 1, + "size": 259, + "vsize": 259, + "weight": 1036, + "locktime": 0, + "vin": [ + { + "txid": "b6a5c12a22f167bb02a76d273f4208ee11a9f32aa455c082d58632ab3acf561b", + "vout": 0, + "scriptSig": { + "asm": "30460221009e9fba682e162c9627b96b7df272006a727988680b956c61baff869f0907b8fb022100a9c19adc7c36144bafe526630783845e5cb9554d30d3edfb56f0740274d507f3[ALL] 046e0efbfac7b1615ad553a6f097615bc63b7cdb3b8e1cb3263b619ba63740012f51c7c5b09390e3577e377b7537e61226e315f95f926444fc5e5f2978c112e448", + "hex": "4930460221009e9fba682e162c9627b96b7df272006a727988680b956c61baff869f0907b8fb022100a9c19adc7c36144bafe526630783845e5cb9554d30d3edfb56f0740274d507f30141046e0efbfac7b1615ad553a6f097615bc63b7cdb3b8e1cb3263b619ba63740012f51c7c5b09390e3577e377b7537e61226e315f95f926444fc5e5f2978c112e448" + }, + "prevout": { + "generated": false, + "height": 99972, + "value": 47.21, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 3a65e10f45bd10ec1eb01ae4577f98fe3256bcba OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(16KnEp9ThwKEyt8rLSuqP3fJ1BLdgHLbRt)#s0qxp947", + "hex": "76a9143a65e10f45bd10ec1eb01ae4577f98fe3256bcba88ac", + "address": "16KnEp9ThwKEyt8rLSuqP3fJ1BLdgHLbRt", + "type": "pubkeyhash" + } + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 45.83, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 b73e9e01933351ca076faf8e0d94dd58079d0b1f OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1HhufprdPc1mVabWxovGxLJYt4avD5Mvrf)#tsu2kvce", + "hex": "76a914b73e9e01933351ca076faf8e0d94dd58079d0b1f88ac", + "address": "1HhufprdPc1mVabWxovGxLJYt4avD5Mvrf", + "type": "pubkeyhash" + } + }, + { + "value": 1.38, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 1aca0bdf0d2cee63db19aa4a484f45a4e26a880c OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(13SecR7EGTXQ4LHGWvYhbAEUbMnFpyMWHG)#pkxgnn7a", + "hex": "76a9141aca0bdf0d2cee63db19aa4a484f45a4e26a880c88ac", + "address": "13SecR7EGTXQ4LHGWvYhbAEUbMnFpyMWHG", + "type": "pubkeyhash" + } + } + ], + "fee": 0.0, + "hex": "01000000011b56cf3aab3286d582c055a42af3a911ee08423f276da702bb67f1222ac1a5b6000000008c4930460221009e9fba682e162c9627b96b7df272006a727988680b956c61baff869f0907b8fb022100a9c19adc7c36144bafe526630783845e5cb9554d30d3edfb56f0740274d507f30141046e0efbfac7b1615ad553a6f097615bc63b7cdb3b8e1cb3263b619ba63740012f51c7c5b09390e3577e377b7537e61226e315f95f926444fc5e5f2978c112e448ffffffff02c0072b11010000001976a914b73e9e01933351ca076faf8e0d94dd58079d0b1f88ac80b63908000000001976a9141aca0bdf0d2cee63db19aa4a484f45a4e26a880c88ac00000000" + }, + { + "txid": "a71f74ab78b564004fffedb2357fb4059ddfc629cb29ceeb449fafbf272104ca", + "hash": "a71f74ab78b564004fffedb2357fb4059ddfc629cb29ceeb449fafbf272104ca", + "version": 1, + "size": 258, + "vsize": 258, + "weight": 1032, + "locktime": 0, + "vin": [ + { + "txid": "684f9fa29462e8087741e06735c14c73a7f701d4fa15392c3b87ea0475181b25", + "vout": 1, + "scriptSig": { + "asm": "30450221009bef423141ed1ae60d0a5bcaa57b1673fc96001f0d4e105535cca817ba5a7724022037c399bd30374f22481ffc81327cfca4951c7264b227f765fcd6a429f3d9d208[ALL] 044d0d1b4f194c31a73dbce41c42b4b3946849117c5bb320467e014bad3b1532f28a9a1568ba7108f188e7823b6e618e91d974306701379a27b9339e646e156e7b", + "hex": "4830450221009bef423141ed1ae60d0a5bcaa57b1673fc96001f0d4e105535cca817ba5a7724022037c399bd30374f22481ffc81327cfca4951c7264b227f765fcd6a429f3d9d2080141044d0d1b4f194c31a73dbce41c42b4b3946849117c5bb320467e014bad3b1532f28a9a1568ba7108f188e7823b6e618e91d974306701379a27b9339e646e156e7b" + }, + "prevout": { + "generated": false, + "height": 99972, + "value": 45.07, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 9ee49ccb3cdd636f0d3dcaa61b929e05085909ef OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1FV9danbeszMmEwHHh1kLLJvb6apQYzd6v)#dw9wujuc", + "hex": "76a9149ee49ccb3cdd636f0d3dcaa61b929e05085909ef88ac", + "address": "1FV9danbeszMmEwHHh1kLLJvb6apQYzd6v", + "type": "pubkeyhash" + } + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 43.59, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 ef7f5d9e1bc6ed68cfe0b1db9d8f09cef0f3ba4a OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1NqM5NX71DeACSauu4uiiRbuKpfkqC53Zi)#sut2yqt9", + "hex": "76a914ef7f5d9e1bc6ed68cfe0b1db9d8f09cef0f3ba4a88ac", + "address": "1NqM5NX71DeACSauu4uiiRbuKpfkqC53Zi", + "type": "pubkeyhash" + } + }, + { + "value": 1.48, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 c22420641cea028c9e06c4d9104c1646f8b17690 OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1JhXNL9wfV7RfF5GourYkhLt8j3yq8vfhs)#ygee8f7r", + "hex": "76a914c22420641cea028c9e06c4d9104c1646f8b1769088ac", + "address": "1JhXNL9wfV7RfF5GourYkhLt8j3yq8vfhs", + "type": "pubkeyhash" + } + } + ], + "fee": 0.0, + "hex": "0100000001251b187504ea873b2c3915fad401f7a7734cc13567e0417708e86294a29f4f68010000008b4830450221009bef423141ed1ae60d0a5bcaa57b1673fc96001f0d4e105535cca817ba5a7724022037c399bd30374f22481ffc81327cfca4951c7264b227f765fcd6a429f3d9d2080141044d0d1b4f194c31a73dbce41c42b4b3946849117c5bb320467e014bad3b1532f28a9a1568ba7108f188e7823b6e618e91d974306701379a27b9339e646e156e7bffffffff02c00fd103010000001976a914ef7f5d9e1bc6ed68cfe0b1db9d8f09cef0f3ba4a88ac004dd208000000001976a914c22420641cea028c9e06c4d9104c1646f8b1769088ac00000000" + }, + { + "txid": "fda204502a3345e08afd6af27377c052e77f1fefeaeb31bdd45f1e1237ca5470", + "hash": "fda204502a3345e08afd6af27377c052e77f1fefeaeb31bdd45f1e1237ca5470", + "version": 1, + "size": 258, + "vsize": 258, + "weight": 1032, + "locktime": 0, + "vin": [ + { + "txid": "a747be4b876b33e57c7414f539ee981f022c8703cb644fc0fc3e2f0a5fdd8634", + "vout": 1, + "scriptSig": { + "asm": "304502201cadddc2838598fee7dc35a12b340c6bde8b389f7bfd19a1252a17c4b5ed2d71022100c1a251bbecb14b058a8bd77f65de87e51c47e95904f4c0e9d52eddc21c1415ac[ALL] 04fe7df86d58aafa9246ca6fd30c905714533c25f700e2329b8ecec8aa52083b844baa3a8acd5d6b9732dcb39079bb56ba2711a3580dec824955fce0596a460c11", + "hex": "48304502201cadddc2838598fee7dc35a12b340c6bde8b389f7bfd19a1252a17c4b5ed2d71022100c1a251bbecb14b058a8bd77f65de87e51c47e95904f4c0e9d52eddc21c1415ac014104fe7df86d58aafa9246ca6fd30c905714533c25f700e2329b8ecec8aa52083b844baa3a8acd5d6b9732dcb39079bb56ba2711a3580dec824955fce0596a460c11" + }, + "prevout": { + "generated": false, + "height": 99972, + "value": 41.58, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 f5fbe57d7141522d641f12019838dca498f483f7 OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1PReK55Wrh76JpNn2TjJiGkjeJs9fBPeTE)#lgzfzmm8", + "hex": "76a914f5fbe57d7141522d641f12019838dca498f483f788ac", + "address": "1PReK55Wrh76JpNn2TjJiGkjeJs9fBPeTE", + "type": "pubkeyhash" + } + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 37.91, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 90fac83c9adde91d670dde8755f8b475ab9e427d OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1EDajGvcRHoiaKJiiETFT99MkTYsfH3hjh)#pqute2jy", + "hex": "76a91490fac83c9adde91d670dde8755f8b475ab9e427d88ac", + "address": "1EDajGvcRHoiaKJiiETFT99MkTYsfH3hjh", + "type": "pubkeyhash" + } + }, + { + "value": 3.67, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 37f691b3e8ee5dcb56c2e31af4c80caa2df3b09b OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(166uYUb7ogk1xyxSSYQzdXRefdbYJaMTjs)#jc9mymg3", + "hex": "76a91437f691b3e8ee5dcb56c2e31af4c80caa2df3b09b88ac", + "address": "166uYUb7ogk1xyxSSYQzdXRefdbYJaMTjs", + "type": "pubkeyhash" + } + } + ], + "fee": 0.0, + "hex": "01000000013486dd5f0a2f3efcc04f64cb03872c021f98ee39f514747ce5336b874bbe47a7010000008b48304502201cadddc2838598fee7dc35a12b340c6bde8b389f7bfd19a1252a17c4b5ed2d71022100c1a251bbecb14b058a8bd77f65de87e51c47e95904f4c0e9d52eddc21c1415ac014104fe7df86d58aafa9246ca6fd30c905714533c25f700e2329b8ecec8aa52083b844baa3a8acd5d6b9732dcb39079bb56ba2711a3580dec824955fce0596a460c11ffffffff02c011f6e1000000001976a91490fac83c9adde91d670dde8755f8b475ab9e427d88acc0f9df15000000001976a91437f691b3e8ee5dcb56c2e31af4c80caa2df3b09b88ac00000000" + }, + { + "txid": "d3cd1ee6655097146bdae1c177eb251de92aed9045a0959edc6b91d7d8c1f158", + "hash": "d3cd1ee6655097146bdae1c177eb251de92aed9045a0959edc6b91d7d8c1f158", + "version": 1, + "size": 256, + "vsize": 256, + "weight": 1024, + "locktime": 0, + "vin": [ + { + "txid": "19b5039093ede6fbf5ad57902fb6224b71a40330a5322f265b794b27d16b0170", + "vout": 1, + "scriptSig": { + "asm": "3043022061456499582170a94d6b54308f792e37dad28bf0ed7aa61021f0301d2774d378021f4224b33f707efd810a01dd34ea86d6069cd599cc435513a0eef8c83c137bf7[ALL] 04a2c95d6b98e745448eb45ed0ba95cf24dd7c3b16386e1028e24a0358ee4afc33e2f0199139853edaf32845d8a42254c75f7dc8add3286c682c650fbd93f0a4a1", + "hex": "463043022061456499582170a94d6b54308f792e37dad28bf0ed7aa61021f0301d2774d378021f4224b33f707efd810a01dd34ea86d6069cd599cc435513a0eef8c83c137bf7014104a2c95d6b98e745448eb45ed0ba95cf24dd7c3b16386e1028e24a0358ee4afc33e2f0199139853edaf32845d8a42254c75f7dc8add3286c682c650fbd93f0a4a1" + }, + "prevout": { + "generated": false, + "height": 99972, + "value": 34.98, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 685ff3d453721067d6ec797790bfa39a7d077e95 OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1AWtDqxSAZ1Z8KfUPTJ6AxeiryhDymLSSA)#xf79k2v2", + "hex": "76a914685ff3d453721067d6ec797790bfa39a7d077e9588ac", + "address": "1AWtDqxSAZ1Z8KfUPTJ6AxeiryhDymLSSA", + "type": "pubkeyhash" + } + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 30.84, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 1b11c6acaa5223013f3a3240fdb024ecd9f81354 OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(13U8YHPZRTUpFjJEr57nNxPNkYhzgWo9Kr)#w2grwkrm", + "hex": "76a9141b11c6acaa5223013f3a3240fdb024ecd9f8135488ac", + "address": "13U8YHPZRTUpFjJEr57nNxPNkYhzgWo9Kr", + "type": "pubkeyhash" + } + }, + { + "value": 4.14, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 ada27ca87bbaa1ee6fb1cb61bb0a29baaf6da2c9 OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1Gq6YyhbJpeJyLewQ1kRuMS6cXkuHZGjyt)#9rehud68", + "hex": "76a914ada27ca87bbaa1ee6fb1cb61bb0a29baaf6da2c988ac", + "address": "1Gq6YyhbJpeJyLewQ1kRuMS6cXkuHZGjyt", + "type": "pubkeyhash" + } + } + ], + "fee": 0.0, + "hex": "010000000170016bd1274b795b262f32a53003a4714b22b62f9057adf5fbe6ed939003b5190100000089463043022061456499582170a94d6b54308f792e37dad28bf0ed7aa61021f0301d2774d378021f4224b33f707efd810a01dd34ea86d6069cd599cc435513a0eef8c83c137bf7014104a2c95d6b98e745448eb45ed0ba95cf24dd7c3b16386e1028e24a0358ee4afc33e2f0199139853edaf32845d8a42254c75f7dc8add3286c682c650fbd93f0a4a1ffffffff02001bd2b7000000001976a9141b11c6acaa5223013f3a3240fdb024ecd9f8135488ac8023ad18000000001976a914ada27ca87bbaa1ee6fb1cb61bb0a29baaf6da2c988ac00000000" + }, + { + "txid": "cb00f8a0573b18faa8c4f467b049f5d202bf1101d9ef2633bc611be70376a4b4", + "hash": "cb00f8a0573b18faa8c4f467b049f5d202bf1101d9ef2633bc611be70376a4b4", + "version": 1, + "size": 258, + "vsize": 258, + "weight": 1032, + "locktime": 0, + "vin": [ + { + "txid": "ad64f480d64cf274152f0eb7616ff201dd619e54e6ae4bba5a6aec31f091ffc8", + "vout": 0, + "scriptSig": { + "asm": "304502210082235e21a2300022738dabb8e1bbd9d19cfb1e7ab8c30a23b0afbb8d178abcf3022024bf68e256c534ddfaf966bf908deb944305596f7bdcc38d69acad7f9c868724[ALL] 04174f9eef1157dc1ad5eac198250b70d1c3b04b2fca12ad1483f07358486f02909b088bbc83f4de55f767f6cdf9d424aa02b5eeaffa08394d39b717895fc08d0a", + "hex": "48304502210082235e21a2300022738dabb8e1bbd9d19cfb1e7ab8c30a23b0afbb8d178abcf3022024bf68e256c534ddfaf966bf908deb944305596f7bdcc38d69acad7f9c868724014104174f9eef1157dc1ad5eac198250b70d1c3b04b2fca12ad1483f07358486f02909b088bbc83f4de55f767f6cdf9d424aa02b5eeaffa08394d39b717895fc08d0a" + }, + "prevout": { + "generated": false, + "height": 99972, + "value": 31.26, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 d287eeaa879be1934c53813dcd94381505ad7294 OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1LCBk2UbhSSDomkT5NSUJCKw7teGFpyBDq)#25my60xw", + "hex": "76a914d287eeaa879be1934c53813dcd94381505ad729488ac", + "address": "1LCBk2UbhSSDomkT5NSUJCKw7teGFpyBDq", + "type": "pubkeyhash" + } + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 11.28, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 fb32df708f0610901f6d1b6df8c9c368fe0d981c OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1PuDYrYxsXkBgvfq5hpaG2w3qpegEgGxXU)#t3m907cn", + "hex": "76a914fb32df708f0610901f6d1b6df8c9c368fe0d981c88ac", + "address": "1PuDYrYxsXkBgvfq5hpaG2w3qpegEgGxXU", + "type": "pubkeyhash" + } + }, + { + "value": 19.98, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 462c501c70fb996d15ac0771e7fc8d3ca3f72018 OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(17Q3PLzmgzdSJ6uoUKJXUXKfS7bHV1bHrM)#hwq9zwgq", + "hex": "76a914462c501c70fb996d15ac0771e7fc8d3ca3f7201888ac", + "address": "17Q3PLzmgzdSJ6uoUKJXUXKfS7bHV1bHrM", + "type": "pubkeyhash" + } + } + ], + "fee": 0.0, + "hex": "0100000001c8ff91f031ec6a5aba4baee6549e61dd01f26f61b70e2f1574f24cd680f464ad000000008b48304502210082235e21a2300022738dabb8e1bbd9d19cfb1e7ab8c30a23b0afbb8d178abcf3022024bf68e256c534ddfaf966bf908deb944305596f7bdcc38d69acad7f9c868724014104174f9eef1157dc1ad5eac198250b70d1c3b04b2fca12ad1483f07358486f02909b088bbc83f4de55f767f6cdf9d424aa02b5eeaffa08394d39b717895fc08d0affffffff0200ea3b43000000001976a914fb32df708f0610901f6d1b6df8c9c368fe0d981c88ac800f1777000000001976a914462c501c70fb996d15ac0771e7fc8d3ca3f7201888ac00000000" + }, + { + "txid": "05d07bb2de2bda1115409f99bf6b626d23ecb6bed810d8be263352988e4548cb", + "hash": "05d07bb2de2bda1115409f99bf6b626d23ecb6bed810d8be263352988e4548cb", + "version": 1, + "size": 257, + "vsize": 257, + "weight": 1028, + "locktime": 0, + "vin": [ + { + "txid": "80c6f121c3e9fe0a59177e49874d8c703cbadee0700a782e4002e87d862373c6", + "vout": 1, + "scriptSig": { + "asm": "3044022042734b25f54845d662e6499b75ff8529ff47f42fd224498a9f752d212326dbfa0220523e4b7b570bbb1f3af02baa2c04ea8eb7b0fccb1522cced130b666ae9a9d014[ALL] 04b5a23b922949877e9eaf7512897ed091958e2e8cf05b0d0eb9064e7976043fde6023b4e2c188b7e38ef94eec6845dc4933f5e8635f1f6a3702290956aa9e284b", + "hex": "473044022042734b25f54845d662e6499b75ff8529ff47f42fd224498a9f752d212326dbfa0220523e4b7b570bbb1f3af02baa2c04ea8eb7b0fccb1522cced130b666ae9a9d014014104b5a23b922949877e9eaf7512897ed091958e2e8cf05b0d0eb9064e7976043fde6023b4e2c188b7e38ef94eec6845dc4933f5e8635f1f6a3702290956aa9e284b" + }, + "prevout": { + "generated": false, + "height": 99997, + "value": 138.31, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 cb4339639d59a2682838e51f7ab5ad17dad64f2a OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(1KXkhm335oR51GfQ8zRtn5EaDZpXtym9wW)#wpnwtl7e", + "hex": "76a914cb4339639d59a2682838e51f7ab5ad17dad64f2a88ac", + "address": "1KXkhm335oR51GfQ8zRtn5EaDZpXtym9wW", + "type": "pubkeyhash" + } + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 138.26, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 36e5884215f7d3044be5d37bdd8c987d9d942c84 OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(161GTYJhuvdLQoTM4KRsqKovZdHLkapUu4)#nuwj5c8l", + "hex": "76a91436e5884215f7d3044be5d37bdd8c987d9d942c8488ac", + "address": "161GTYJhuvdLQoTM4KRsqKovZdHLkapUu4", + "type": "pubkeyhash" + } + }, + { + "value": 0.05, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 60085d6838f8a44a21a0de56ff963cfa6242a961 OP_EQUALVERIFY OP_CHECKSIG", + "desc": "addr(19kmtcoDHC25WkXrBBLFAjsFGVKgM1SHtp)#pc7wwks3", + "hex": "76a91460085d6838f8a44a21a0de56ff963cfa6242a96188ac", + "address": "19kmtcoDHC25WkXrBBLFAjsFGVKgM1SHtp", + "type": "pubkeyhash" + } + } + ], + "fee": 0.0, + "hex": "0100000001c67323867de802402e780a70e0deba3c708c4d87497e17590afee9c321f1c680010000008a473044022042734b25f54845d662e6499b75ff8529ff47f42fd224498a9f752d212326dbfa0220523e4b7b570bbb1f3af02baa2c04ea8eb7b0fccb1522cced130b666ae9a9d014014104b5a23b922949877e9eaf7512897ed091958e2e8cf05b0d0eb9064e7976043fde6023b4e2c188b7e38ef94eec6845dc4933f5e8635f1f6a3702290956aa9e284bffffffff0280041838030000001976a91436e5884215f7d3044be5d37bdd8c987d9d942c8488ac404b4c00000000001976a91460085d6838f8a44a21a0de56ff963cfa6242a96188ac00000000" + } + ] +} \ No newline at end of file diff --git a/tests/data/block-99999.json b/tests/data/block-99999.json new file mode 100644 index 0000000..98c7592 --- /dev/null +++ b/tests/data/block-99999.json @@ -0,0 +1,50 @@ +{ + "hash": "000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250", + "confirmations": 100002, + "height": 99999, + "version": 1, + "versionHex": "00000001", + "merkleroot": "110ed92f558a1e3a94976ddea5c32f030670b5c58c3cc4d857ac14d7a1547a90", + "time": 1293623731, + "mediantime": 1293622434, + "nonce": 3892545714, + "bits": "1b04864c", + "difficulty": 14484.1623612254, + "chainwork": "000000000000000000000000000000000000000000000000064492eaf00f2520", + "nTx": 1, + "previousblockhash": "0000000000002103637910d267190996687fb095880d432c6531a527c8ec53d1", + "nextblockhash": "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506", + "strippedsize": 215, + "size": 215, + "weight": 860, + "tx": [ + { + "txid": "110ed92f558a1e3a94976ddea5c32f030670b5c58c3cc4d857ac14d7a1547a90", + "hash": "110ed92f558a1e3a94976ddea5c32f030670b5c58c3cc4d857ac14d7a1547a90", + "version": 1, + "size": 134, + "vsize": 134, + "weight": 536, + "locktime": 0, + "vin": [ + { + "coinbase": "044c86041b013e", + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 50.0, + "n": 0, + "scriptPubKey": { + "asm": "04d190840cfdae05af3d2febca52b0466b6efb02b44036a5d0d70659a53f7b84b736c5a05ed81e90af70985d59ffb3d1b91364f70b4d2b3b7553e177b1ceaff322 OP_CHECKSIG", + "desc": "pk(04d190840cfdae05af3d2febca52b0466b6efb02b44036a5d0d70659a53f7b84b736c5a05ed81e90af70985d59ffb3d1b91364f70b4d2b3b7553e177b1ceaff322)#uhumlu8n", + "hex": "4104d190840cfdae05af3d2febca52b0466b6efb02b44036a5d0d70659a53f7b84b736c5a05ed81e90af70985d59ffb3d1b91364f70b4d2b3b7553e177b1ceaff322ac", + "type": "pubkey" + } + } + ], + "hex": "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff07044c86041b013effffffff0100f2052a01000000434104d190840cfdae05af3d2febca52b0466b6efb02b44036a5d0d70659a53f7b84b736c5a05ed81e90af70985d59ffb3d1b91364f70b4d2b3b7553e177b1ceaff322ac00000000" + } + ] +} \ No newline at end of file diff --git a/tests/data/block_100000.json b/tests/data/block_100000.json deleted file mode 100644 index 8e39669..0000000 --- a/tests/data/block_100000.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "hash": "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506", - "confirmations": 164055, - "strippedsize": 957, - "size": 957, - "weight": 3828, - "height": 100000, - "version": 1, - "versionHex": "00000001", - "merkleroot": "f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766", - "tx": [ - "8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87", - "fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4", - "6359f0868171b1d194cbee1af2f16ea598ae8fad666d9b012c8ed2b79a236ec4", - "e9a66845e05d5abc0ad04ec80f774a7e585c6e8db975962d069a522137b80c1d" - ], - "time": 1293623863, - "mediantime": 1293622620, - "nonce": 274148111, - "bits": "1b04864c", - "difficulty": 14484.1623612254, - "chainwork": "0000000000000000000000000000000000000000000000000644cb7f5234089e", - "nTx": 4, - "previousblockhash": "000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250", - "nextblockhash": "00000000000080b66c911bd5ba14a74260057311eaeb1982802f7010f1a9f090" -} \ No newline at end of file diff --git a/tests/data/block_100001.json b/tests/data/block_100001.json deleted file mode 100644 index f3f7c92..0000000 --- a/tests/data/block_100001.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "hash": "00000000000080b66c911bd5ba14a74260057311eaeb1982802f7010f1a9f090", - "confirmations": 164415, - "strippedsize": 3308, - "size": 3308, - "weight": 13232, - "height": 100001, - "version": 1, - "versionHex": "00000001", - "merkleroot": "7fe79307aeb300d910d9c4bec5bacb4c7e114c7dfd6789e19f3a733debb3bb6a", - "tx": [ - "bb28a1a5b3a02e7657a81c38355d56c6f05e80b9219432e3352ddcfc3cb6304c", - "fbde5d03b027d2b9ba4cf5d4fecab9a99864df2637b25ea4cbcb1796ff6550ca", - "8131ffb0a2c945ecaf9b9063e59558784f9c3a74741ce6ae2a18d0571dac15bb", - "d6c7cb254aa7a5fd446e8b48c307890a2d4e426da8ad2e1191cc1d8bbe0677d7", - "ce29e5407f5e4c9ad581c337a639f3041b24220d5aa60370d96a39335538810b", - "45a38677e1be28bd38b51bc1a1c0280055375cdf54472e04c590a989ead82515", - "c5abc61566dbb1c4bce5e1fda7b66bed22eb2130cea4b721690bc1488465abc9", - "a71f74ab78b564004fffedb2357fb4059ddfc629cb29ceeb449fafbf272104ca", - "fda204502a3345e08afd6af27377c052e77f1fefeaeb31bdd45f1e1237ca5470", - "d3cd1ee6655097146bdae1c177eb251de92aed9045a0959edc6b91d7d8c1f158", - "cb00f8a0573b18faa8c4f467b049f5d202bf1101d9ef2633bc611be70376a4b4", - "05d07bb2de2bda1115409f99bf6b626d23ecb6bed810d8be263352988e4548cb" - ], - "time": 1293624404, - "mediantime": 1293623177, - "nonce": 2613872960, - "bits": "1b04864c", - "difficulty": 14484.1623612254, - "chainwork": "00000000000000000000000000000000000000000000000006450413b458ec1c", - "nTx": 12, - "previousblockhash": "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506" -} \ No newline at end of file diff --git a/tests/data/block_99999.json b/tests/data/block_99999.json deleted file mode 100644 index 6246f0d..0000000 --- a/tests/data/block_99999.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "hash": "000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250", - "confirmations": 165593, - "strippedsize": 215, - "size": 215, - "weight": 860, - "height": 99999, - "version": 1, - "versionHex": "00000001", - "merkleroot": "110ed92f558a1e3a94976ddea5c32f030670b5c58c3cc4d857ac14d7a1547a90", - "tx": [ - "110ed92f558a1e3a94976ddea5c32f030670b5c58c3cc4d857ac14d7a1547a90" - ], - "time": 1293623731, - "mediantime": 1293622434, - "nonce": 3892545714, - "bits": "1b04864c", - "difficulty": 14484.1623612254, - "chainwork": "000000000000000000000000000000000000000000000000064492eaf00f2520", - "nTx": 1, - "previousblockhash": "0000000000002103637910d267190996687fb095880d432c6531a527c8ec53d1", - "nextblockhash": "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506" -} \ No newline at end of file diff --git a/tests/data/tx_4a1817bf3dacbdb2f726e551979a4a1d27ec3ba9e4dda14fd90d0312f1cf068b.json b/tests/data/tx_4a1817bf3dacbdb2f726e551979a4a1d27ec3ba9e4dda14fd90d0312f1cf068b.json deleted file mode 100644 index d484423..0000000 --- a/tests/data/tx_4a1817bf3dacbdb2f726e551979a4a1d27ec3ba9e4dda14fd90d0312f1cf068b.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "txid": "4a1817bf3dacbdb2f726e551979a4a1d27ec3ba9e4dda14fd90d0312f1cf068b", - "hash": "4a1817bf3dacbdb2f726e551979a4a1d27ec3ba9e4dda14fd90d0312f1cf068b", - "version": 1, - "size": 306, - "vsize": 306, - "weight": 1224, - "locktime": 0, - "vin": [ - { - "txid": "0da0736b8fa1c61870479b36ff716ca0d97c45b3fbf8ddd9c3b023ae80bcb25b", - "vout": 0, - "scriptSig": { - "asm": "30450220690414b0cece222dd5fece6c0459d460f4f19e56e6e778d5837e964ae17ae8a6022100d60e1fec5f83496bc24ecd99861e09cebaf29d2690069a909b01c5bd4bf828b1[ALL]", - "hex": "4830450220690414b0cece222dd5fece6c0459d460f4f19e56e6e778d5837e964ae17ae8a6022100d60e1fec5f83496bc24ecd99861e09cebaf29d2690069a909b01c5bd4bf828b101" - }, - "sequence": 4294967295 - }, - { - "txid": "57b91cd09fa7868eaad9928d67e8d573046f63ee8ef50d32d7e6270905394742", - "vout": 0, - "scriptSig": { - "asm": "30450221009ad66755338edfca8b713149b3a17cd69166b4c6804530644171c5d6c8fb74ab022011530cb894ee873db5010f9a3a28cf3a8e71ddcade634510e6a47a0fcdbc46d0[ALL]", - "hex": "4830450221009ad66755338edfca8b713149b3a17cd69166b4c6804530644171c5d6c8fb74ab022011530cb894ee873db5010f9a3a28cf3a8e71ddcade634510e6a47a0fcdbc46d001" - }, - "sequence": 4294967295 - } - ], - "vout": [ - { - "value": 0.07, - "n": 0, - "scriptPubKey": { - "asm": "OP_DUP OP_HASH160 6dc5889a5b0e0d3d38b951f5ef2a701ec98a8914 OP_EQUALVERIFY OP_CHECKSIG", - "hex": "76a9146dc5889a5b0e0d3d38b951f5ef2a701ec98a891488ac", - "reqSigs": 1, - "type": "pubkeyhash", - "addresses": [ - "1B1RHnXpachCAVHpQt81rZ17z9yYoipPBp" - ] - } - }, - { - "value": 100.0, - "n": 1, - "scriptPubKey": { - "asm": "OP_DUP OP_HASH160 f4b004c3ca2e7f96f9fc5bca767708967af67a44 OP_EQUALVERIFY OP_CHECKSIG", - "hex": "76a914f4b004c3ca2e7f96f9fc5bca767708967af67a4488ac", - "reqSigs": 1, - "type": "pubkeyhash", - "addresses": [ - "1PJnjo4n2Rt5jWTUrCRr4inK2XmFPXqFC7" - ] - } - } - ], - "hex": "01000000025bb2bc80ae23b0c3d9ddf8fbb3457cd9a06c71ff369b477018c6a18f6b73a00d00000000494830450220690414b0cece222dd5fece6c0459d460f4f19e56e6e778d5837e964ae17ae8a6022100d60e1fec5f83496bc24ecd99861e09cebaf29d2690069a909b01c5bd4bf828b101ffffffff424739050927e6d7320df58eee636f0473d5e8678d92d9aa8e86a79fd01cb95700000000494830450221009ad66755338edfca8b713149b3a17cd69166b4c6804530644171c5d6c8fb74ab022011530cb894ee873db5010f9a3a28cf3a8e71ddcade634510e6a47a0fcdbc46d001ffffffff02c0cf6a00000000001976a9146dc5889a5b0e0d3d38b951f5ef2a701ec98a891488ac00e40b54020000001976a914f4b004c3ca2e7f96f9fc5bca767708967af67a4488ac00000000", - "blockhash": "00000000000092de6cd6e12e089c82d0e0ccda29c3311000b2947e9bef27fb2c", - "confirmations": 66055, - "time": 1303363832, - "blocktime": 1303363832 -} \ No newline at end of file diff --git a/tests/rpc_mock.py b/tests/rpc_mock.py index 25744fb..19a9b91 100644 --- a/tests/rpc_mock.py +++ b/tests/rpc_mock.py @@ -19,16 +19,15 @@ def __init__(self, host=None, port=None): # Load test data into local dicts def load_testdata(self): - p = Path(TEST_DATA_PATH) + p = Path(__file__).parent.joinpath('data') files = [x for x in p.iterdir() if x.is_file() and x.name.endswith('json')] for f in files: if f.name.startswith("block"): - height = f.name[6:-5] with f.open() as jf: raw_block = json.load(jf) block_hash = raw_block['hash'] - self.heights[int(height)] = block_hash + self.heights[raw_block['height']] = block_hash self.blocks[block_hash] = raw_block elif f.name.startswith("tx"): tx_hash = f.name[3:-5] diff --git a/tests/test_blockchain.py b/tests/test_blockchain.py index d9f9b84..979493e 100644 --- a/tests/test_blockchain.py +++ b/tests/test_blockchain.py @@ -3,7 +3,7 @@ from tests.rpc_mock import BitcoinProxyMock from bitcoingraph.blockchain import Blockchain, BlockchainException -from bitcoingraph.model import Input, Output +from bitcoingraph.model import Input, Output, CoinbaseInput BH1 = "000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250" BH1_HEIGHT = 99999 @@ -59,18 +59,6 @@ def test_nextblockhash(self): block = self.blockchain.get_block_by_hash(BH3) self.assertFalse(block.has_next_block()) - def hasnextblock(self): - block = self.blockchain.get_block_by_hash(BH1) - self.assertTrue(block.has_next_block()) - block = self.blockchain.get_block_by_hash(BH3) - self.assertFalse(block.has_next_block()) - - def test_nextblock(self): - block = self.blockchain.get_block_by_hash(BH1) - self.assertEqual(block.next_block.height, BH2_HEIGHT) - block = self.blockchain.get_block_by_hash(BH3) - self.assertIsNone(block.next_block) - def test_tx_count(self): block = self.blockchain.get_block_by_hash(BH1) self.assertEqual(len(block.transactions), 1) @@ -99,63 +87,66 @@ def test_difficulty(self): def test_prev_hash(self): block = self.blockchain.get_block_by_hash(BH1) - self.assertEqual(block.previous_block.hash, "0000000000002103637910d267190996687fb095880d432c6531a527c8ec53d1") + self.assertEqual(block.previous_block_hash, "0000000000002103637910d267190996687fb095880d432c6531a527c8ec53d1") class TestTxInput(TestBlockchainObject): def test_is_coinbase(self): - tx = self.blockchain.get_transaction(TX1) + block = self.blockchain.get_block_by_hash(BH1) + tx = block.transactions[0] tx_input = tx.inputs[0] self.assertTrue(tx_input.is_coinbase) def test_is_not_coinbase(self): - tx = self.blockchain.get_transaction(TX2) + block = self.blockchain.get_block_by_hash(BH2) + tx = block.transactions[1] tx_input = tx.inputs[0] self.assertFalse(tx_input.is_coinbase) def test_prev_tx_hash(self): - tx = self.blockchain.get_transaction(TX2) - tx_input = tx.inputs[0] - self.assertEqual(tx_input.output_reference['txid'], TX3) - - def test_prev_tx_coinbase(self): - tx = self.blockchain.get_transaction(TX1) + block = self.blockchain.get_block_by_hash(BH2) + tx = block.transactions[1] tx_input = tx.inputs[0] - self.assertIsNone(tx_input.output_reference) + self.assertEqual(tx_input.output_reference.txid, "87a157f3fd88ac7907c05fc55e271dc4acdc5605d187d646604ca8c0e9382e03") def test_tx_output_index(self): - tx = self.blockchain.get_transaction(TX2) - tx_input = tx.inputs[0] - self.assertEqual(tx_input.output_reference['vout'], 0) - - def test_prev_tx_output(self): - tx = self.blockchain.get_transaction(TX2) + block = self.blockchain.get_block_by_hash(BH2) + tx = block.transactions[1] tx_input = tx.inputs[0] - prev_tx_output = tx_input.output - self.assertIsNotNone(prev_tx_output) + self.assertEqual(tx_input.output_reference.index, 0) def test_addresses(self): - tx = self.blockchain.get_transaction(TX2) + block = self.blockchain.get_block_by_hash(BH2) + tx = block.transactions[1] tx_input = tx.inputs[0] - self.assertEqual("12bCGuqBso4K8pKoNFXHUR4eMZg8j4xqN3", - tx_input.output.addresses[0]) + self.assertEqual(len(tx_input.output_reference.addresses), 1) + self.assertEqual( + tx_input.output_reference.addresses[0], + "1BNwxHGaFbeUBitpjy2AsKpJ29Ybxntqvb", + ) class TestTxOutput(TestBlockchainObject): + def get_tx(self): + block = self.blockchain.get_block_by_hash(BH1) + return block.transactions[0] def test_index(self): - tx = self.blockchain.get_transaction(TX2) + block = self.blockchain.get_block_by_hash(BH2) + tx = block.transactions[1] self.assertEqual(0, tx.outputs[0].index) self.assertEqual(1, tx.outputs[1].index) def test_value(self): - tx = self.blockchain.get_transaction(TX2) + block = self.blockchain.get_block_by_hash(BH2) + tx = block.transactions[1] self.assertEqual(5.56000000, tx.outputs[0].value) self.assertEqual(44.44000000, tx.outputs[1].value) def test_addresses(self): - tx = self.blockchain.get_transaction(TX2) + block = self.blockchain.get_block_by_hash(BH2) + tx = block.transactions[1] self.assertEqual("1JqDybm2nWTENrHvMyafbSXXtTk5Uv5QAn", tx.outputs[0].addresses[0]) self.assertEqual("1EYTGtG4LnFfiMvjJdsU7GMGCQvsRSjYhx", @@ -165,7 +156,8 @@ def test_empty_addresses(self): """ Test if empty list is return when no output addresses are present. """ - tx = self.blockchain.get_transaction(TXE) + block = self.blockchain.get_block_by_hash(BH2) + tx = block.transactions[3] self.assertEqual(["pk_0469b7eaf1cca8a7c8592ad49313b4cb6474a845604456d48b4b252904e1d61ceda95ac987ad163e957bdbd2da2736861fbfad93dbf8e0a218308a49d94ab9a077"], tx.outputs[0].addresses) self.assertFalse(tx.outputs[1].addresses) @@ -174,40 +166,48 @@ def test_empty_addresses(self): class TestTransaction(TestBlockchainObject): def test_blocktime(self): - tx = self.blockchain.get_transaction(TX1) - self.assertEqual(tx.block.timestamp, 1293623863) + block = self.blockchain.get_block_by_hash(BH2) + self.assertEqual(block.timestamp, 1293623863) def test_blocktime_as_dt(self): - tx = self.blockchain.get_transaction(TX1) - self.assertEqual(tx.block.formatted_time(), "2010-12-29 11:57:43") + block = self.blockchain.get_block_by_hash(BH2) + self.assertEqual(block.formatted_time(), "2010-12-29 11:57:43") def test_id(self): - tx = self.blockchain.get_transaction(TX1) + block = self.blockchain.get_block_by_hash(BH2) + tx = block.transactions[0] self.assertEqual(tx.txid, TX1) def test_get_input_count(self): - tx = self.blockchain.get_transaction(TX1) + block = self.blockchain.get_block_by_hash(BH2) + tx = block.transactions[0] self.assertEqual(len(tx.inputs), 1) - tx = self.blockchain.get_transaction(TX2) + tx = block.transactions[1] self.assertEqual(len(tx.inputs), 1) def test_get_inputs(self): - tx = self.blockchain.get_transaction(TX1) + block = self.blockchain.get_block_by_hash(BH2) + tx = block.transactions[0] for tx_input in tx.inputs: - self.assertIsInstance(tx_input, Input) + self.assertIsInstance(tx_input, CoinbaseInput) def test_is_coinbase_tx(self): - self.assertTrue(self.blockchain.get_transaction(TX1).is_coinbase()) - self.assertFalse(self.blockchain.get_transaction(TX2).is_coinbase()) + block = self.blockchain.get_block_by_hash(BH2) + tx1 = block.transactions[0] + tx2 = block.transactions[1] + self.assertTrue(tx1.is_coinbase()) + self.assertFalse(tx2.is_coinbase()) def test_get_output_count(self): - tx = self.blockchain.get_transaction(TX1) + block = self.blockchain.get_block_by_hash(BH2) + tx = block.transactions[0] self.assertEqual(len(tx.outputs), 1) - tx = self.blockchain.get_transaction(TX2) + tx = block.transactions[1] self.assertEqual(len(tx.outputs), 2) def test_get_outputs(self): - tx = self.blockchain.get_transaction(TX1) + block = self.blockchain.get_block_by_hash(BH2) + tx = block.transactions[0] for tx_output in tx.outputs: self.assertIsInstance(tx_output, Output) @@ -230,15 +230,6 @@ def test_get_blocks_in_range(self): self.assertEqual(blocks[1].height, 100000) self.assertEqual(blocks[2].height, 100001) - def test_get_transaction(self): - tx = self.blockchain.get_transaction(TX1) - self.assertEqual(tx.txid, TX1) - - def test_get_transactions(self): - tx_ids = [TX1, TX2] - txs = self.blockchain.get_transactions(tx_ids) - self.assertEqual(2, len(txs)) - def test_get_max_blockheight(self): max_height = self.blockchain.get_max_block_height() self.assertEqual(max_height, 100001) diff --git a/tests/test_entities.py b/tests/test_entities.py new file mode 100644 index 0000000..f81d0e6 --- /dev/null +++ b/tests/test_entities.py @@ -0,0 +1,408 @@ +import os + +import neo4j +import pytest + +from bitcoingraph.entities import EntityGrouping, get_addresses_grouped_by_transaction + + +@pytest.fixture +def session(): + host = os.environ.get("NEO4J_HOST", "127.0.0.1") + port = os.environ.get("NEO4J_PORT", "7687") + user = os.environ.get("NEO4J_USER", "neo4j") + psw = os.environ.get("NEO4J_PASSWORD", "neo4j") + + driver = neo4j.GraphDatabase.driver( + f"bolt://{host}:{port}", + auth=(user, psw), + connection_timeout=3600) + + with driver.session() as session: + session.run("MATCH (n) DETACH DELETE n") + yield session + + driver.close() + +def test_get_addresses_grouped_by_transaction(session): + session.run(""" + MERGE (b1:Block {height: 1})-[:CONTAINS]->(t1:Transaction {txid: 1}) + MERGE (t1)<-[:INPUT]-(o11:Output) + MERGE (t1)<-[:INPUT]-(o12:Output) + MERGE (o11)-[:USES]->(a11:Address {address: "11"}) + MERGE (o12)-[:USES]->(a12:Address {address: "12"}) + MERGE (a11)-[:GENERATES]->(a11g:Address {address: "11_1g"}) + MERGE (a11)-[:GENERATES]->(a12g:Address {address: "11_2g"}) + MERGE (a12f:Address {address: "12father"})-[:GENERATES]->(a12) + MERGE (b1)-[:CONTAINS]->(t2:Transaction {txid: 2}) + MERGE (t2)<-[:INPUT]-(o21:Output) + MERGE (t2)<-[:INPUT]-(o22:Output) + MERGE (o21)-[:USES]->(a21:Address {address: "21"}) + MERGE (o22)-[:USES]->(a22:Address {address: "22"}) + """) + + rows = get_addresses_grouped_by_transaction(session, 1, 1) + + assert len(rows) == 2 + assertions = 0 + + for row in rows: + if len(row["generated"]): + assertions |= 1 + assert set(row["addresses"]) == {'11', '12'} + assert set(row["generated"]) == {'11_1g', '11_2g', '12father'} + else: + assertions |= 2 + assert set(row["addresses"]) == {'21', '22'} + assert set(row["generated"]) == set([]) + + assert assertions == 3 + + +class TestSaveEntities(): + def test_separate_no_entities(self, session): + session.run(""" + MERGE (t1:Address {address: "1"}) + MERGE (t2:Address {address: "2"}) + """) + + grouping = EntityGrouping() + grouping.entity_idx_to_addresses = {"1": ["1", "2"]} + + def run_save(): + grouping.save_entities(session) + response = session.run(""" + MATCH (a1:Address)<-[:OWNER_OF]-(e:Entity)-[:OWNER_OF]->(a2:Address) + WHERE a1.address = "1" AND a2.address = "2" + RETURN a1,a2,e + """) + return response.data() + + result = run_save() + assert len(result) == 1 + assert result[0]["e"]["entity_id"] == "1" + + # check that re-running the same query doesn't alter the result + result = run_save() + assert len(result) == 1 + assert result[0]["e"]["entity_id"] == "1" + + def test_separate_one_has_entity(self, session): + session.run(""" + MERGE (t1:Address {address: "1"})<-[:OWNER_OF]-(e:Entity {entity_id: "123"}) + MERGE (t2:Address {address: "2"}) + """) + + grouping = EntityGrouping() + grouping.entity_idx_to_addresses = {"1": ["1", "2"]} + + def run_save(): + grouping.save_entities(session) + response = session.run(""" + MATCH (a1:Address)<-[:OWNER_OF]-(e:Entity)-[:OWNER_OF]->(a2:Address) + WHERE a1.address = "1" AND a2.address = "2" + RETURN a1,a2,e + """) + return response.data() + + data = run_save() + assert len(data) == 1 + assert data[0]["e"]["entity_id"] == "123" + + # re-run to make sure the same query doesn't modify data + data = run_save() + assert len(data) == 1 + assert data[0]["e"]["entity_id"] == "123" + + def test_separate_both_have_entity(self, session): + session.run(""" + MERGE (t1:Address {address: "1"})<-[:OWNER_OF]-(e1:Entity {entity_id: "123"}) + MERGE (t2:Address {address: "2"})<-[:OWNER_OF]-(e2:Entity {entity_id: "456"}) + """) + + grouping = EntityGrouping() + grouping.entity_idx_to_addresses = {"1": ["1", "2"]} + + def run_save(): + grouping.save_entities(session) + response = session.run(""" + MATCH (a1:Address)<-[:OWNER_OF]-(e:Entity)-[:OWNER_OF]->(a2:Address) + WHERE a1.address = "1" AND a2.address = "2" + RETURN distinct a1,a2,e + """) + return response.data() + + data = run_save() + assert len(data) == 1 + assert data[0]["e"]["entity_id"] == "456" + + data = session.run("""MATCH (e:Entity {entity_id: "123"}) RETURN e""").data() + assert len(data) == 0 + + # re-run + data = run_save() + assert len(data) == 1 + assert data[0]["e"]["entity_id"] == "456" + + data = session.run("""MATCH (e:Entity {entity_id: "123"}) RETURN e""").data() + assert len(data) == 0 + + def test_separate_three_have_entity(self, session): + session.run(""" + MERGE (t1:Address {address: "1"})<-[:OWNER_OF]-(e1:Entity {entity_id: "123"}) + MERGE (t2:Address {address: "2"})<-[:OWNER_OF]-(e2:Entity {entity_id: "456"}) + MERGE (t3:Address {address: "3"})<-[:OWNER_OF]-(e3:Entity {entity_id: "789"}) + """) + + grouping = EntityGrouping() + grouping.entity_idx_to_addresses = {"1": ["1", "2", "3"]} + + def run_save(): + grouping.save_entities(session) + response = session.run(""" + MATCH (e:Entity) + WITH e + OPTIONAL MATCH (e)-[:OWNER_OF]->(a:Address) + RETURN e, collect(a) as addresses + """) + return response.data() + + data = run_save() + assert len(data) == 1 + assert data[0]["e"]["entity_id"] == "789" + assert len(data[0]["addresses"]) + assert set((x["address"] for x in data[0]["addresses"])) == {"1", "2", "3"} + + # re-run + data = run_save() + assert len(data) == 1 + assert data[0]["e"]["entity_id"] == "789" + assert len(data[0]["addresses"]) + assert set((x["address"] for x in data[0]["addresses"])) == {"1", "2", "3"} + + def test_separate_two_have_entities_different_size_keep_largest(self, session): + session.run(""" + MERGE (t1:Address {address: "1"})<-[:OWNER_OF]-(e1:Entity {entity_id: "123"}) + MERGE (t2:Address {address: "2"}) + MERGE (t2)<-[:OWNER_OF]-(e1) + MERGE (t3:Address {address: "3"})<-[:OWNER_OF]-(e2:Entity {entity_id: "456"}) + MERGE (t4:Address {address: "4"})<-[:OWNER_OF]-(e3:Entity {entity_id: "789"}) + """) + + grouping = EntityGrouping() + grouping.entity_idx_to_addresses = {"1": ["1", "3", "4"]} + + def run_save(): + grouping.save_entities(session) + response = session.run(""" + MATCH (e:Entity) + WITH e + OPTIONAL MATCH (e)-[:OWNER_OF]->(a:Address) + RETURN e, collect(a) as addresses + """) + return response.data() + + data = run_save() + assert len(data) == 1 + assert data[0]["e"]["entity_id"] == "123" + assert len(data[0]["addresses"]) + assert set((x["address"] for x in data[0]["addresses"])) == {"1", "2", "3", "4"} + + # re-run + data = run_save() + assert len(data) == 1 + assert data[0]["e"]["entity_id"] == "123" + assert len(data[0]["addresses"]) + assert set((x["address"] for x in data[0]["addresses"])) == {"1", "2", "3", "4"} + + def test_separate_two_entities_and_independent_addresses(self, session): + session.run(""" + MERGE (t0:Address {address: "0"})<-[:OWNER_OF]-(e1:Entity {entity_id: "123"}) + MERGE (t1:Address {address: "1"}) + MERGE (t1)<-[:OWNER_OF]-(e1) + MERGE (t2:Address {address: "2"})<-[:OWNER_OF]-(e2:Entity {entity_id: "456"}) + MERGE (t3:Address {address: "3"}) + MERGE (t4:Address {address: "4"}) + MERGE (t5:Address {address: "5"}) + """) + + grouping = EntityGrouping() + grouping.entity_idx_to_addresses = {"1": ["1", "2", "3", "4"]} + + def run_save(): + grouping.save_entities(session) + response = session.run(""" + MATCH (e:Entity) + WITH e + OPTIONAL MATCH (e)-[:OWNER_OF]->(a:Address) + RETURN e, collect(a) as addresses + """) + return response.data() + + data = run_save() + assert len(data) == 1 + assert data[0]["e"]["entity_id"] == "123" + assert len(data[0]["addresses"]) + assert set((x["address"] for x in data[0]["addresses"])) == {"0", "1", "2", "3", "4"} + + count_addresses = session.run("MATCH (a:Address) RETURN count(distinct a) as ca").data("ca")[0]['ca'] + assert count_addresses == 6 + + # re-run + data = run_save() + assert len(data) == 1 + assert data[0]["e"]["entity_id"] == "123" + assert len(data[0]["addresses"]) + assert set((x["address"] for x in data[0]["addresses"])) == {"0", "1", "2", "3", "4"} + + count_addresses = session.run("MATCH (a:Address) RETURN count(distinct a) as ca").data("ca")[0]['ca'] + assert count_addresses == 6 + + def test_merge_names_present(self, session): + session.run(""" + MERGE (t1:Address {address: "1"})<-[:OWNER_OF]-(e1:Entity {entity_id: "123", name: "foo"}) + MERGE (t2:Address {address: "2"})<-[:OWNER_OF]-(e2:Entity {entity_id: "456", name: "bar"}) + MERGE (t3:Address {address: "3"}) + """) + + grouping = EntityGrouping() + grouping.entity_idx_to_addresses = {"1": ["1", "2", "3"]} + + grouping.save_entities(session) + response = session.run(""" + MATCH (e:Entity) + WITH e + OPTIONAL MATCH (e)-[:OWNER_OF]->(a:Address) + RETURN e, collect(a) as addresses + """) + data = response.data() + + assert len(data) == 1 + assert data[0]["e"]["entity_id"] == "456" + assert data[0]["e"]["name"] == "foo+bar" + assert len(data[0]["addresses"]) + assert set((x["address"] for x in data[0]["addresses"])) == {"1", "2", "3"} + + def test_merge_names_none(self, session): + session.run(""" + MERGE (t1:Address {address: "1"})<-[:OWNER_OF]-(e1:Entity {entity_id: "123"}) + MERGE (t2:Address {address: "2"})<-[:OWNER_OF]-(e2:Entity {entity_id: "456"}) + MERGE (t3:Address {address: "3"}) + """) + + grouping = EntityGrouping() + grouping.entity_idx_to_addresses = {"1": ["1", "2", "3"]} + + grouping.save_entities(session) + response = session.run(""" + MATCH (e:Entity) + WITH e + OPTIONAL MATCH (e)-[:OWNER_OF]->(a:Address) + RETURN e, collect(a) as addresses + """) + data = response.data() + + assert len(data) == 1 + assert data[0]["e"]["entity_id"] == "456" + assert data[0]["e"].get("name") is None + assert len(data[0]["addresses"]) + assert set((x["address"] for x in data[0]["addresses"])) == {"1", "2", "3"} + + def test_merge_names_first_exists(self, session): + session.run(""" + MERGE (t1:Address {address: "1"})<-[:OWNER_OF]-(e1:Entity {entity_id: "123", name: "foo"}) + MERGE (t2:Address {address: "2"})<-[:OWNER_OF]-(e2:Entity {entity_id: "456"}) + MERGE (t3:Address {address: "3"}) + """) + + grouping = EntityGrouping() + grouping.entity_idx_to_addresses = {"1": ["1", "2", "3"]} + + grouping.save_entities(session) + response = session.run(""" + MATCH (e:Entity) + WITH e + OPTIONAL MATCH (e)-[:OWNER_OF]->(a:Address) + RETURN e, collect(a) as addresses + """) + data = response.data() + + assert len(data) == 1 + assert data[0]["e"]["entity_id"] == "456" + assert data[0]["e"]["name"] == "foo" + assert len(data[0]["addresses"]) + assert set((x["address"] for x in data[0]["addresses"])) == {"1", "2", "3"} + + def test_merge_names_second_exists(self, session): + session.run(""" + MERGE (t1:Address {address: "1"})<-[:OWNER_OF]-(e1:Entity {entity_id: "123"}) + MERGE (t2:Address {address: "2"})<-[:OWNER_OF]-(e2:Entity {entity_id: "456", name: "foo"}) + MERGE (t3:Address {address: "3"}) + """) + + grouping = EntityGrouping() + grouping.entity_idx_to_addresses = {"1": ["1", "2", "3"]} + + grouping.save_entities(session) + response = session.run(""" + MATCH (e:Entity) + WITH e + OPTIONAL MATCH (e)-[:OWNER_OF]->(a:Address) + RETURN e, collect(a) as addresses + """) + data = response.data() + + assert len(data) == 1 + assert data[0]["e"]["entity_id"] == "456" + assert data[0]["e"]["name"] == "foo" + assert len(data[0]["addresses"]) + assert set((x["address"] for x in data[0]["addresses"])) == {"1", "2", "3"} + + +class TestMergeEntities: + def test_simple_case(self, session): + session.run(""" + // Two entities + MERGE (a1:Address {address: "1"})<-[:OWNER_OF]-(e1:Entity {entity_id: "1"}) + MERGE (a2:Address {address: "2"})<-[:OWNER_OF]-(e2:Entity {entity_id: "2"}) + MERGE (a1)-[:GENERATES]->(a2) + """) + + session.run(""" + MATCH (e1:Entity)-[:OWNER_OF]->(a1:Address)-[:GENERATES]->(a2:Address)<-[:OWNER_OF]-(e2:Entity) + WITH [e1,e2] as entities + CALL apoc.refactor.mergeNodes(entities) + YIELD node + RETURN node + """) + + def test_generator_has_entity(self, session): + session.run(""" + MERGE (a1:Address {address: "1"})<-[:OWNER_OF]-(e1:Entity {entity_id: "1"}) + MERGE (a1)-[:GENERATES]->(a2) + """) + + def test_generated_has_entity(self, session): + session.run(""" + MERGE (a1:Address {address: "1"})<-[:OWNER_OF]-(e1:Entity {entity_id: "1"}) + MERGE (a2:Address {address: "2"})<-[:OWNER_OF]-(e2:Entity {entity_id: "2"}) + MERGE (a1)-[:GENERATES]->(a2) + """) + + def test_circular_dependence(self, session): + merge_query = [] + for i in range(6): + merge_query.append(f"MERGE (a{i+1}:Address {{address: '{i}'}})") + + merge_query = "\n".join(merge_query) + session.run(merge_query + """ + MERGE (a1)<-[:OWNER_OF]-(e1:Entity {entity_id: "1"}) + MERGE (a1)-[:GENERATES]->(a2) + MERGE (a2)<-[:OWNER_OF]-(e2:Entity {entity_id: "2"}) + MERGE (e2)-[:OWNER_OF]->(a3) + MERGE (a3)-[:GENERATES]->(a4) + MERGE (a4)<-[:OWNER_OF]-(e3:Entity {entity_id: "3"}) + MERGE (e3)-[:OWNER_OF]->(a5) + MERGE (a5)<-[:GENERATES]-(a6) + MERGE (e1)-[:OWNER_OF]->(a6) + """) \ No newline at end of file diff --git a/tests/test_graph.py b/tests/test_graph.py new file mode 100644 index 0000000..0073118 --- /dev/null +++ b/tests/test_graph.py @@ -0,0 +1,110 @@ +import os +import unittest + +import neo4j.exceptions + +from bitcoingraph.blockchain import Blockchain +from bitcoingraph.graphdb import GraphController +from tests.rpc_mock import BitcoinProxyMock + +BH1 = "000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250" +BH2 = "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506" +BH3 = "00000000000080b66c911bd5ba14a74260057311eaeb1982802f7010f1a9f090" + +class TestBlockchainObject(unittest.TestCase): + + def setUp(self): + self.bitcoin_proxy = BitcoinProxyMock() + self.blockchain = Blockchain(self.bitcoin_proxy) + self.graph_db = GraphController( + os.environ.get("NEO4J_HOST", "127.0.0.1"), + os.environ.get("NEO4J_PORT", "7687"), + os.environ.get("NEO4J_USER", "neo4j"), + os.environ.get("NEO4J_PASSWORD", "neo4j"), + ) + self.initialise() + + def initialise(self): + self.assertIsNotNone(self.blockchain) + self.assertIsNotNone(self.bitcoin_proxy) + with self.graph_db.driver.session() as session: + session.run("MATCH (n) DETACH DELETE n") + + try: + session.run("CREATE CONSTRAINT IF NOT EXISTS FOR (a:Address) REQUIRE a.address IS UNIQUE;") + session.run("CREATE CONSTRAINT IF NOT EXISTS FOR (b:Block) REQUIRE b.height IS UNIQUE;") + session.run("CREATE CONSTRAINT IF NOT EXISTS FOR (o:Output) REQUIRE o.txid_n IS UNIQUE;") + session.run("CREATE CONSTRAINT IF NOT EXISTS FOR (t:Transaction) REQUIRE t.txid IS UNIQUE;") + session.run("CREATE CONSTRAINT IF NOT EXISTS FOR (e:Entity) REQUIRE e.entity_id IS UNIQUE;") + except neo4j.exceptions.DatabaseError as e: + if not e.code == "Neo.DatabaseError.Schema.ConstraintCreationFailed": + raise e + + session.run("CALL db.awaitIndexes(120)") + + for i in range(99999, 100002): + block = self.blockchain.get_block_by_height(i) + self.graph_db.add_block(block) + +class TestLoading(TestBlockchainObject): + def test_blocks(self): + with self.graph_db.driver.session() as session: + blocks = session.run("MATCH (b:Block) RETURN b ORDER BY b.height ASC").data("b") + self.assertEqual(len(blocks), 3) + self.assertEqual(blocks[0]['b']['hash'], BH1) + self.assertEqual(blocks[1]['b']['hash'], BH2) + self.assertEqual(blocks[2]['b']['hash'], BH3) + + blocks = session.run("MATCH (b:Block)-[:APPENDS]->(prevB:Block) RETURN b ORDER BY b.height ASC").data("b") + self.assertEqual(len(blocks), 2) + self.assertEqual(blocks[0]['b']['height'], 100000) + self.assertEqual(blocks[1]['b']['height'], 100001) + + + def test_transactions_global(self): + with self.graph_db.driver.session() as session: + result = session.run("MATCH (b:Block)-[:CONTAINS]->(t:Transaction) RETURN b, collect(t) as txs ORDER BY b.height ASC") + + rows = result.data() + self.assertEqual(len(rows[0]['txs']), 1) + self.assertEqual(len(rows[1]['txs']), 4) + self.assertEqual(len(rows[2]['txs']), 12) + + ct1 = session.run("MATCH (t:Transaction) RETURN count(t) as ct").value("ct")[0] + ct2 = session.run("MATCH (t:Transaction) WHERE t.txid is not null RETURN count(t) as ct").value("ct")[0] + self.assertEqual(ct1, 17) + self.assertEqual(ct1, ct2) + + + def test_transaction_input_output_same_block(self): + with self.graph_db.driver.session() as session: + result = session.run(""" + MATCH (b:Block)-[:CONTAINS]->(t:Transaction)-[:OUTPUT]->(o:Output)-[:INPUT]->(t1:Transaction)<-[:CONTAINS]-(b) + RETURN b,t,o,t1 + """).data() + + self.assertEqual(len(result), 1) + result = result[0] + self.assertEqual(result['t']['txid'], "bb28a1a5b3a02e7657a81c38355d56c6f05e80b9219432e3352ddcfc3cb6304c") + self.assertEqual(result['t1']['txid'], "fbde5d03b027d2b9ba4cf5d4fecab9a99864df2637b25ea4cbcb1796ff6550ca") + + def test_generated_addresses(self): + with self.graph_db.driver.session() as session: + result = session.run(""" + MATCH (a:Address) + WHERE a.address STARTS WITH "pk" + WITH a + OPTIONAL MATCH (a)-[:GENERATES]->(generated) + RETURN a, collect(generated) as generated + """).data() + + self.assertEqual(len(result), 4) + for row in result: + self.assertIsNotNone(row['generated']) + self.assertEqual(len(row['generated']), 2) + + + def test_entities(self): + with self.graph_db.driver.session() as session: + result = session.run("MATCH (e:Entity) WITH e OPTIONAL MATCH (e)-[:OWNER_OF]->(a) RETURN e, collect(a) as owned ORDER BY e.entity_id ASC").data() + self.assertEqual(len(result), 4)