diff --git a/Cargo.lock b/Cargo.lock
index 9da2f580..b2a1275c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5809,9 +5809,9 @@ dependencies = [
[[package]]
name = "self_encryption"
-version = "0.36.0"
+version = "0.36.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47ab904569f88dcbde4f0feadb693c184577dc81e8243f96bb725e72a779c637"
+checksum = "6a6c9e93b470f0fb747a609cfd7c4a23ea39bfbc1813de3d00fa429a9dc99e38"
dependencies = [
"bincode",
"blake3",
diff --git a/Cargo.toml b/Cargo.toml
index ec8f5ce5..f3978b22 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,4 +1,3 @@
[workspace]
members = ["ant-core", "ant-cli"]
resolver = "2"
-
diff --git a/README.md b/README.md
index ea1a7ade..007e9267 100644
--- a/README.md
+++ b/README.md
@@ -35,6 +35,50 @@ transports use `record.rs` for BLAKE3 verification. Native
`Client::data_download_range` and the browser media reader call the same range
implementation.
+Browser downloads and range reads have no 1 GB file cap. File sizes and offsets
+use 64-bit arithmetic internally; the JavaScript API accepts exact, nonnegative
+`number` positions through `Number.MAX_SAFE_INTEGER` (just under 8 PiB). The
+resolved DataMap and seek index still occupy memory proportional to the number
+of chunks; content buffers stay bounded, including for seeks past 4 GiB.
+Uploads retain their existing size limits.
+
+`downloadPublicFile(file, concurrency?, onProgress?, { maxMemoryBytes?, signal? })`
+and its private-file counterpart allocate the output as one JavaScript
+`Uint8Array` and copy each decrypted chunk into place as it arrives, so WASM
+holds only the records in flight. Progress is reported as
+`Downloaded chunk n/total`, and an `AbortSignal` cancels the download. `maxMemoryBytes` limits the output buffer,
+not total process memory; without it, allocation is attempted up to the
+JavaScript engine's buffer limit. Allocation errors reject with guidance to use
+streaming, since browsers do not expose a reliable amount of free memory.
+
+For large downloads, pass a `WritableStream` to `BrowserFileReader.pipeTo`.
+For example, after the application obtains a file handle from a user gesture:
+
+```js
+const reader = await client.openPublicFile(address);
+try {
+ const writable = await fileHandle.createWritable();
+ const { bytesWritten, hash } = await reader.pipeTo(writable);
+} finally {
+ reader.close();
+}
+```
+
+The same API works with `openPrivateFile({ data_map })`. `pipeTo(writable,
+{ start?, end?, signal?, onProgress? })` optionally streams a half-open byte
+range and reports `(bytesWritten, totalBytes)` after each write. Chunks are
+fetched concurrently and written in order, at most 4 MiB per write; fetching
+continues during writes until 32 MiB of plaintext is held. Invalid calls reject
+without touching the destination; otherwise the destination is closed on
+success, aborted on failure (an abort during its close may come too late to
+undo the commit), and its writer lock released. The result contains
+the byte count and BLAKE3 of the written range, and an `AbortSignal` cancels
+the call. `reader.close()` releases the records read-ahead holds and makes later
+calls fail. `readRange(start, length)` remains available for media and custom
+sinks, with a 4 MiB per-call limit. The application chooses a memory budget and
+supplies its disk destination; the core does not open file pickers or silently
+select a path.
+
The adapters supply QUIC or WebRTC discovery/GET requests, runtime timers,
caches, progress callbacks, and output handling. Browser descriptors and wallet
callbacks remain browser API concerns. Native filesystem streaming still uses
diff --git a/ant-core/Cargo.toml b/ant-core/Cargo.toml
index 8abc470c..d435fdaf 100644
--- a/ant-core/Cargo.toml
+++ b/ant-core/Cargo.toml
@@ -24,7 +24,7 @@ rmp-serde = "1"
serde = { version = "1", features = ["derive"] }
serde_bytes = "0.11"
serde_json = "1"
-self_encryption = "0.36"
+self_encryption = "0.36.2"
# Portable WebRTC Direct profile shared with ant-node.
saorsa-transport = { version = "0.37.0", default-features = false, features = ["webrtc"] }
thiserror = "2"
@@ -91,6 +91,7 @@ serde-wasm-bindgen = { version = "0.6", optional = true }
wasm-bindgen = { version = "0.2", optional = true }
wasm-bindgen-futures = { version = "0.4", optional = true }
web-sys = { version = "0.3", optional = true, features = [
+ "AbortSignal",
"Event",
"MessageEvent",
"RtcConfiguration",
@@ -104,6 +105,8 @@ web-sys = { version = "0.3", optional = true, features = [
"RtcSdpType",
"RtcSessionDescription",
"RtcSessionDescriptionInit",
+ "WritableStream",
+ "WritableStreamDefaultWriter",
] }
gloo-timers = { version = "0.3", features = ["futures"], optional = true }
# Deterministic mock-node signing for generated-WASM transport regression tests.
diff --git a/ant-core/browser-tests/README.md b/ant-core/browser-tests/README.md
index 32a1ebd2..229ecf45 100644
--- a/ant-core/browser-tests/README.md
+++ b/ant-core/browser-tests/README.md
@@ -75,3 +75,26 @@ or node RPC mocks are installed. It also checks that a closed network client
rejects reconnection. Temporary node data is removed on shutdown.
The suite uses local funds only and verifies that the RPC belongs to the local
Anvil devnet before invoking the wallet.
+
+## Large-file disk streaming
+
+`large-file.mjs` is an opt-in check, not run in CI, that a file larger than
+4 GiB streams to disk in real Chromium. Build the production bindings as above
+and a release CLI (`cargo build --release --bin ant` in the workspace root),
+start `node start-devnet.mjs` in another terminal, then run:
+
+```sh
+node large-file.mjs [path to ant]
+```
+
+It writes the 4,303,347,835-byte plaintext of the
+[`large-file.json`](../wasm-tests/fixtures/large-file.json) fixture to a
+temporary file and uploads it with `ant`, under a throwaway home so the upload
+stays out of your upload history, and checks it lands on the fixture's
+address. Chromium then opens the file, reads across 4 GiB, and pipes all of it
+into the origin private file system with `pipeTo`. The run checks the BLAKE3
+hash and the stored size and bytes, and that a complete in-memory download over
+a 64 MiB budget fails and points to `pipeTo`. It exits non-zero if any check
+fails and needs about 5 GB of free disk. The file is one repeated byte, so its
+records compress to about 67 KB: the run checks correctness and local
+decryption and writing, not network throughput.
diff --git a/ant-core/browser-tests/large-file.mjs b/ant-core/browser-tests/large-file.mjs
new file mode 100644
index 00000000..edc324a2
--- /dev/null
+++ b/ant-core/browser-tests/large-file.mjs
@@ -0,0 +1,122 @@
+// Opt-in check, not run in CI, that a >4 GiB public file streams to disk in real Chromium.
+// With `node start-devnet.mjs` running, production bindings in ../wasm-tests/pkg and a release `ant`:
+// node large-file.mjs [path to ant, default ../../target/release/ant]
+// Uploads the fixture's plaintext natively, then pipes it into the origin private file system.
+import { chromium } from "@playwright/test";
+import { spawnSync } from "node:child_process";
+import { createWriteStream } from "node:fs";
+import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
+import { createServer } from "node:http";
+import { tmpdir } from "node:os";
+import { join, resolve } from "node:path";
+import { Readable } from "node:stream";
+import { pipeline } from "node:stream/promises";
+
+const DEVNET_API = "http://127.0.0.1:35000/api";
+const PKG = resolve("../wasm-tests/pkg");
+const WRITE_BLOCK_BYTES = 4 * 1024 * 1024;
+// A complete in-memory download over this budget must fail before any transfer.
+const BUDGET_BYTES = 64 * 1024 * 1024;
+const FOUR_GIB = 2 ** 32;
+// Bytes read on each side of a probed position.
+const PROBE_BYTES = 8;
+
+const ant = resolve(process.argv[2] ?? "../../target/release/ant");
+const file = JSON.parse(await readFile("../wasm-tests/fixtures/large-file.json", "utf8"));
+const devnet = await (await fetch(`${DEVNET_API}/devnet-manifest.json`)).json();
+const { endpoints } = await (await fetch(`${DEVNET_API}/browser-manifest.json`)).json();
+const directory = await mkdtemp(join(tmpdir(), "ant-large-file-"));
+const server = createServer(async (request, response) => {
+ const name = request.url?.split("?")[0];
+ if (name === "/") { response.setHeader("Content-Type", "text/html"); response.end("
Large file "); return; }
+ if (!["/ant_core.js", "/ant_core_bg.wasm"].includes(name)) { response.writeHead(404).end(); return; }
+ response.setHeader("Content-Type", name.endsWith(".wasm") ? "application/wasm" : "text/javascript");
+ response.end(await readFile(join(PKG, name.slice(1))));
+});
+let context;
+try {
+ // The fixture's plaintext, so the native upload must land on the fixture's address.
+ const source = join(directory, "large-file.bin");
+ const block = Buffer.alloc(WRITE_BLOCK_BYTES, file.byte);
+ await pipeline(Readable.from((function* () {
+ for (let left = file.size; left > 0; left -= block.length) yield block.subarray(0, Math.min(left, block.length));
+ })()), createWriteStream(source));
+ const manifest = join(directory, "devnet-manifest.json");
+ await writeFile(manifest, JSON.stringify(devnet));
+ // A throwaway home keeps the upload out of the real upload history.
+ const home = join(directory, "home");
+ const upload = spawnSync(ant, ["--json", "--devnet-manifest", manifest, "--allow-loopback", "--evm-network", "local",
+ "file", "upload", source, "--public"], { encoding: "utf8", stdio: ["ignore", "pipe", "inherit"],
+ env: { ...process.env, HOME: home, XDG_DATA_HOME: home, XDG_CONFIG_HOME: home, SECRET_KEY: devnet.evm.wallet_private_key } });
+ if (upload.status !== 0) throw new Error(`ant file upload failed with ${upload.status ?? upload.error}`);
+ const uploaded = JSON.parse(upload.stdout);
+ await rm(source);
+
+ await new Promise(done => server.listen(0, "127.0.0.1", done));
+ // A persistent profile gives the origin private file system a normal disk quota.
+ context = await chromium.launchPersistentContext(join(directory, "profile"), { headless: true,
+ args: ["--force-fieldtrials=WebRTC-NoSdpMangleUfrag/Enabled/"] });
+ const page = await context.newPage();
+ const errors = [];
+ page.on("pageerror", error => errors.push(error.message));
+ await page.goto(`http://127.0.0.1:${server.address().port}/`);
+ const result = await page.evaluate(async ({ endpoint, file, budget, boundary, probe }) => {
+ const { default: init, BrowserNetworkClient } = await import("/ant_core.js");
+ await init();
+ const seconds = since => Math.round(performance.now() - since) / 1000;
+ const filled = bytes => bytes.every(value => value === file.byte);
+ const client = new BrowserNetworkClient([endpoint]);
+ let started = performance.now();
+ const reader = await client.openPublicFile(file.address);
+ const openSeconds = seconds(started);
+ const seek = await reader.readRange(boundary - probe, 2 * probe);
+
+ const root = await navigator.storage.getDirectory();
+ const handle = await root.getFileHandle("large-file.bin", { create: true });
+ let progressCalls = 0, lastProgress;
+ started = performance.now();
+ const piped = await reader.pipeTo(await handle.createWritable(),
+ { onProgress: written => { progressCalls++; lastProgress = written; } });
+ const pipeSeconds = seconds(started);
+ const stored = await handle.getFile();
+ const around = new Uint8Array(await stored.slice(boundary - probe, boundary + probe).arrayBuffer());
+ const tail = new Uint8Array(await stored.slice(stored.size - 2 * probe).arrayBuffer());
+ const size = reader.size;
+ reader.close();
+
+ let budgetError;
+ try { await client.downloadPublicFile(file.address, undefined, undefined, { maxMemoryBytes: budget }); }
+ catch (error) { budgetError = String(error); }
+ // Informational: whether this browser could hold the whole file in one buffer at all.
+ let allocation;
+ try { allocation = `allocated ${new Uint8Array(file.size).length} bytes`; }
+ catch (error) { allocation = `${error.name}: ${error.message}`; }
+ client.close(); client.free();
+ await root.removeEntry("large-file.bin");
+ return { size, seekFilled: seek.length === 2 * probe && filled(seek), bytesWritten: piped.bytesWritten,
+ hash: piped.hash, storedSize: stored.size, storedFilled: filled(around) && filled(tail),
+ progressCalls, lastProgress, budgetError, allocation, openSeconds, pipeSeconds };
+ }, { endpoint: endpoints[0], file: { address: file.address, size: file.size, byte: file.byte },
+ budget: BUDGET_BYTES, boundary: FOUR_GIB, probe: PROBE_BYTES });
+
+ const checks = {
+ uploadAddress: uploaded.address === file.address,
+ size: result.size === file.size,
+ seekAcross4GiB: result.seekFilled,
+ bytesWritten: result.bytesWritten === file.size,
+ hash: result.hash === file.hash,
+ storedSize: result.storedSize === file.size,
+ storedBytes: result.storedFilled,
+ progress: result.lastProgress === file.size,
+ budgetPointsAtPipeTo: result.budgetError?.includes("pipeTo") ?? false,
+ noPageErrors: errors.length === 0,
+ };
+ console.log(JSON.stringify({ browser: context.browser()?.version() ?? chromium.name(),
+ uploadSeconds: uploaded.elapsed_secs, result, errors, checks }, null, 2));
+ const failed = Object.keys(checks).filter(name => !checks[name]);
+ if (failed.length > 0) { console.error(`failed: ${failed.join(", ")}`); process.exitCode = 1; }
+} finally {
+ await context?.close();
+ server.close();
+ await rm(directory, { recursive: true, force: true });
+}
diff --git a/ant-core/examples/generate-browser-large-file.rs b/ant-core/examples/generate-browser-large-file.rs
new file mode 100644
index 00000000..d703da34
--- /dev/null
+++ b/ant-core/examples/generate-browser-large-file.rs
@@ -0,0 +1,55 @@
+//! Regenerate the compact native fixture used by the WASM large-file tests:
+//! cargo run -p ant-core --release --example generate-browser-large-file
+//!
+//! Encrypts >4 GiB with bounded memory. Repeated plaintext compresses well;
+//! all encrypted records fit in a small fixture without allocating the file.
+use bytes::Bytes;
+use std::collections::HashMap;
+
+/// Plaintext byte repeated through the file; the tests check it on every read.
+const FILL_BYTE: u8 = 0x5a;
+/// Whole chunks past the 4 GiB position, so reads and seeks cross it.
+const CHUNKS_PAST_4_GIB: u64 = 2;
+/// A short final chunk, so the file does not end on a chunk boundary.
+const TAIL_BYTES: u64 = 123;
+
+fn main() {
+ let size =
+ (1u64 << 32) + CHUNKS_PAST_4_GIB * self_encryption::MAX_CHUNK_SIZE as u64 + TAIL_BYTES;
+ let block = Bytes::from(vec![FILL_BYTE; self_encryption::MAX_CHUNK_SIZE]);
+ let mut remaining = size as usize;
+ let mut hasher = blake3::Hasher::new();
+ let input = std::iter::from_fn(|| {
+ if remaining == 0 {
+ return None;
+ }
+ let length = remaining.min(block.len());
+ remaining -= length;
+ hasher.update(&block[..length]);
+ Some(block.slice(..length))
+ });
+ let mut encryptor = self_encryption::stream_encrypt(size as usize, input).unwrap();
+ let records: HashMap<_, _> = encryptor.chunks().map(|item| item.unwrap()).collect();
+ let map = encryptor.into_datamap().unwrap();
+ let root =
+ self_encryption::get_root_data_map(map.clone(), &mut |hash| Ok(records[&hash].clone()))
+ .unwrap();
+ assert_eq!(root.original_file_size() as u64, size);
+ let mut retained = records;
+ let map_bytes = rmp_serde::to_vec(&map).unwrap();
+ let address = ant_protocol::compute_address(&map_bytes);
+ retained.insert(self_encryption::XorName(address), Bytes::from(map_bytes));
+ let mut records: Vec<_> = retained.into_iter().map(|(hash, content)| {
+ serde_json::json!({"address": hex::encode(hash.0), "content": hex::encode(content)})
+ }).collect();
+ records.sort_by(|a, b| a["address"].as_str().cmp(&b["address"].as_str()));
+ let fixture = serde_json::json!({
+ "size": size, "byte": FILL_BYTE, "hash": hasher.finalize().to_hex().to_string(),
+ "address": hex::encode(address), "records": records,
+ });
+ let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
+ .join("wasm-tests/fixtures/large-file.json");
+ std::fs::create_dir_all(path.parent().unwrap()).unwrap();
+ std::fs::write(&path, serde_json::to_vec_pretty(&fixture).unwrap()).unwrap();
+ eprintln!("Wrote {}-byte file fixture to {}", size, path.display());
+}
diff --git a/ant-core/src/browser.rs b/ant-core/src/browser.rs
index 5b4b5086..39732dde 100644
--- a/ant-core/src/browser.rs
+++ b/ant-core/src/browser.rs
@@ -27,14 +27,16 @@ pub use protocol::{
mod wasm_transport;
use bytes::Bytes;
-use self_encryption::{DataMap, EncryptedChunk};
+use self_encryption::{ChunkInfo, DataMap, EncryptedChunk};
use serde::{Deserialize, Serialize};
use std::collections::HashSet;
-/// Maximum file size accepted by the browser API (1 GB decimal).
+/// Maximum file size accepted by the browser upload API (1 GB decimal).
///
-/// The page upload path streams through a worker and browser storage. Complete
-/// downloads and the legacy whole-buffer encryption binding remain memory-bound.
+/// The page upload path streams through a worker and browser storage; the
+/// legacy encryption binding remains memory-bound. Downloads are not limited by
+/// this constant: a complete download needs one buffer of the file's size,
+/// while `pipeTo` and range reads hold a bounded amount of plaintext.
pub const MAX_BROWSER_FILE_BYTES: usize = 1_000_000_000;
/// One native self-encryption chunk descriptor exposed to the browser.
@@ -255,16 +257,16 @@ pub fn decrypt_public_file(
}
fn chunk_infos(data_map: &DataMap) -> Vec {
- data_map
- .infos()
- .iter()
- .map(|info| BrowserChunkInfo {
- index: info.index,
- dst_hash: hex::encode(info.dst_hash.0),
- src_hash: hex::encode(info.src_hash.0),
- src_size: info.src_size,
- })
- .collect()
+ data_map.infos().iter().map(browser_chunk_info).collect()
+}
+
+fn browser_chunk_info(info: &ChunkInfo) -> BrowserChunkInfo {
+ BrowserChunkInfo {
+ index: info.index,
+ dst_hash: hex::encode(info.dst_hash.0),
+ src_hash: hex::encode(info.src_hash.0),
+ src_size: info.src_size,
+ }
}
#[cfg(all(target_arch = "wasm32", feature = "browser-wasm"))]
diff --git a/ant-core/src/browser/manifest.rs b/ant-core/src/browser/manifest.rs
index 6b2dc01d..f7f7a13b 100644
--- a/ant-core/src/browser/manifest.rs
+++ b/ant-core/src/browser/manifest.rs
@@ -3,12 +3,19 @@
pub use super::protocol::BrowserPaymentNetwork;
use super::protocol::{normalize_hex, parse_webrtc_direct_multiaddr, BrowserEndpoint};
use super::BrowserChunkInfo;
+use crate::client_engine::files::MIN_FILE_CHUNKS;
use serde::{Deserialize, Serialize};
/// Current browser testnet manifest version.
pub const BROWSER_MANIFEST_VERSION: u16 = 6;
const MAX_DATA_MAP_BYTES: usize = 4 * 1024 * 1024;
-const MAX_FILE_CHUNKS: usize = 1024;
+/// Bounds the sorting and hex normalisation of an untrusted entry's chunk list.
+/// The manifest is already parsed by then, so its size is the caller's bound.
+/// At the native chunk size this admits files of about 1 TiB.
+const MAX_FILE_CHUNKS: usize = 1 << 18;
+/// `Number.MAX_SAFE_INTEGER`: the largest integer JavaScript represents
+/// exactly, which bounds chain IDs, file sizes and byte positions.
+pub const MAX_SAFE_JS_INTEGER: u64 = 9_007_199_254_740_991;
/// A validated WebRTC Direct bootstrap endpoint.
pub type BrowserManifestEndpoint = BrowserEndpoint;
@@ -21,7 +28,7 @@ pub struct PublicFileDescriptor {
/// Public DataMap content address.
pub address: String,
/// Plaintext file size.
- pub size: usize,
+ pub size: u64,
/// Browser MIME type.
pub content_type: String,
/// Whole-file plaintext BLAKE3 hash.
@@ -99,7 +106,7 @@ pub fn validate_browser_payment_network(
) -> Result {
// The JS SDK exposes chain IDs as numbers; reject identities that cannot
// survive that boundary exactly.
- if payment.chain_id > 9_007_199_254_740_991 {
+ if payment.chain_id > MAX_SAFE_JS_INTEGER {
return Err(BrowserManifestError(
"payment chain ID exceeds JavaScript's safe integer range".to_string(),
));
@@ -150,9 +157,7 @@ fn normalize_file(file: &mut PublicFileDescriptor) -> Result<(), BrowserManifest
));
}
file.address = normalize_hex(&file.address, 32).map_err(BrowserManifestError)?;
- if !(self_encryption::MIN_ENCRYPTABLE_BYTES..=super::MAX_BROWSER_FILE_BYTES)
- .contains(&file.size)
- {
+ if !(self_encryption::MIN_ENCRYPTABLE_BYTES as u64..=MAX_SAFE_JS_INTEGER).contains(&file.size) {
return Err(BrowserManifestError(format!(
"invalid public file size {}",
file.size
@@ -165,13 +170,13 @@ fn normalize_file(file: &mut PublicFileDescriptor) -> Result<(), BrowserManifest
file.data_map_size
)));
}
- if !(3..=MAX_FILE_CHUNKS).contains(&file.chunks.len()) {
+ if !(MIN_FILE_CHUNKS..=MAX_FILE_CHUNKS).contains(&file.chunks.len()) {
return Err(BrowserManifestError(
"public file has an invalid self-encryption chunk list".to_string(),
));
}
file.chunks.sort_by_key(|chunk| chunk.index);
- let mut reconstructed_size = 0usize;
+ let mut reconstructed_size = 0u64;
for (expected_index, chunk) in file.chunks.iter_mut().enumerate() {
if chunk.index != expected_index {
return Err(BrowserManifestError(
@@ -180,6 +185,7 @@ fn normalize_file(file: &mut PublicFileDescriptor) -> Result<(), BrowserManifest
}
chunk.dst_hash = normalize_hex(&chunk.dst_hash, 32).map_err(BrowserManifestError)?;
chunk.src_hash = normalize_hex(&chunk.src_hash, 32).map_err(BrowserManifestError)?;
+ // Sizes come from the DataMap, which may use another chunk size.
if chunk.src_size == 0 {
return Err(BrowserManifestError(format!(
"invalid plaintext chunk size {}",
@@ -187,7 +193,7 @@ fn normalize_file(file: &mut PublicFileDescriptor) -> Result<(), BrowserManifest
)));
}
reconstructed_size = reconstructed_size
- .checked_add(chunk.src_size)
+ .checked_add(chunk.src_size as u64)
.ok_or_else(|| BrowserManifestError("file size overflow".to_string()))?;
}
if reconstructed_size != file.size {
@@ -286,4 +292,68 @@ mod tests {
assert_eq!(manifest.files[0].chunks[0].index, 0);
assert_eq!(manifest.payment.chain_id, 31337);
}
+
+ #[test]
+ fn file_descriptors_allow_more_than_four_gib_and_1024_chunks() {
+ let mut file = PublicFileDescriptor {
+ name: "large.bin".into(),
+ address: "11".repeat(32),
+ size: 1030 * self_encryption::MAX_CHUNK_SIZE as u64,
+ content_type: "application/octet-stream".into(),
+ blake3: "22".repeat(32),
+ data_map_size: 256,
+ replicas: 4,
+ chunks: (0..1030)
+ .map(|index| BrowserChunkInfo {
+ index,
+ src_size: self_encryption::MAX_CHUNK_SIZE,
+ src_hash: "33".repeat(32),
+ dst_hash: "44".repeat(32),
+ })
+ .collect(),
+ };
+ assert!(file.size > u32::MAX as u64);
+ normalize_file(&mut file).unwrap();
+ file.size += 1;
+ assert!(normalize_file(&mut file).is_err());
+ file.size = MAX_SAFE_JS_INTEGER + 1;
+ assert!(normalize_file(&mut file).is_err());
+ }
+
+ #[test]
+ fn file_descriptors_accept_other_chunk_sizes_and_bound_chunk_lists() {
+ let chunk = |index, src_size| BrowserChunkInfo {
+ index,
+ src_size,
+ src_hash: "33".repeat(32),
+ dst_hash: "44".repeat(32),
+ };
+ let large_chunk = 2 * self_encryption::MAX_CHUNK_SIZE;
+ let mut file = PublicFileDescriptor {
+ name: "large-chunks.bin".into(),
+ address: "11".repeat(32),
+ size: (MIN_FILE_CHUNKS * large_chunk) as u64,
+ content_type: "application/octet-stream".into(),
+ blake3: "22".repeat(32),
+ data_map_size: 256,
+ replicas: 4,
+ chunks: (0..MIN_FILE_CHUNKS)
+ .map(|index| chunk(index, large_chunk))
+ .collect(),
+ };
+ normalize_file(&mut file).unwrap();
+
+ // Rejected on length alone, before the list is sorted or decoded.
+ file.chunks = (0..=MAX_FILE_CHUNKS)
+ .map(|index| BrowserChunkInfo {
+ index,
+ src_size: 1,
+ src_hash: String::new(),
+ dst_hash: String::new(),
+ })
+ .collect();
+ file.size = file.chunks.len() as u64;
+ let error = normalize_file(&mut file).unwrap_err();
+ assert!(error.to_string().contains("chunk list"));
+ }
}
diff --git a/ant-core/src/browser/wasm_transport.rs b/ant-core/src/browser/wasm_transport.rs
index 5355a084..cb859c82 100644
--- a/ant-core/src/browser/wasm_transport.rs
+++ b/ant-core/src/browser/wasm_transport.rs
@@ -117,6 +117,8 @@ thread_local! {
}
mod bootstrap;
+mod download;
+pub use download::BrowserFileReader;
mod failed_payment;
mod inbox;
mod multiplex;
@@ -2024,14 +2026,18 @@ fn parse_lookup_key(value: &str, label: &str) -> Result {
})
}
-#[derive(Debug, Serialize)]
+#[derive(Debug, Serialize, Deserialize)]
struct BrowserDownloadResult {
- #[serde(with = "serde_bytes")]
- content: Vec,
+ #[serde(with = "serde_wasm_bindgen::preserve")]
+ content: Uint8Array,
hash: String,
file: PublicFileDescriptor,
/// Node that served a public DataMap; absent for a caller-held private DataMap.
- #[serde(rename = "dataMapNode", skip_serializing_if = "Option::is_none")]
+ #[serde(
+ rename = "dataMapNode",
+ default,
+ skip_serializing_if = "Option::is_none"
+ )]
data_map_node: Option,
}
@@ -2105,11 +2111,7 @@ struct BrowserFileReaderOptions {
impl BrowserFileReaderOptions {
fn from_js(options: Option) -> Result {
- options
- .map(serde_wasm_bindgen::from_value)
- .transpose()
- .map(Option::unwrap_or_default)
- .map_err(|error| JsValue::from_str(&error.to_string()))
+ download::options_from_js(options).map_err(|error| JsValue::from_str(&error))
}
}
@@ -2122,10 +2124,10 @@ enum BrowserFileSource {
}
struct ResolvedBrowserFile {
+ /// Descriptor without a chunk list; `index` holds the chunk metadata.
file: PublicFileDescriptor,
- expected_hash: Option,
data_map_node: Option,
- root_data_map: self_encryption::DataMap,
+ index: self_encryption::DataMapIndex,
}
struct UploadRecord {
@@ -2241,88 +2243,6 @@ impl RecordPlacement {
}
}
-/// Random-access public-file reader for media playback and bounded downloads.
-#[wasm_bindgen(js_name = BrowserFileReader)]
-pub struct BrowserFileReader {
- shared: Rc,
- file: PublicFileDescriptor,
- root_data_map: self_encryption::DataMap,
- read_ahead: Rc,
- closed: Cell,
-}
-
-#[wasm_bindgen(js_class = BrowserFileReader)]
-impl BrowserFileReader {
- /// Plaintext file size in bytes.
- #[wasm_bindgen(getter)]
- pub fn size(&self) -> usize {
- self.file.size
- }
-
- /// Browser MIME type advertised by the file descriptor.
- #[wasm_bindgen(getter, js_name = contentType)]
- pub fn content_type(&self) -> String {
- self.file.content_type.clone()
- }
-
- /// Display filename advertised by the file descriptor.
- #[wasm_bindgen(getter)]
- pub fn name(&self) -> String {
- self.file.name.clone()
- }
-
- /// Fetch and decrypt one plaintext byte range without reconstructing the file.
- #[wasm_bindgen(js_name = readRange)]
- pub async fn read_range(&self, start: usize, length: usize) -> Result {
- let content = self
- .read_range_inner(start, length)
- .await
- .map_err(|error| JsValue::from_str(&error))?;
- Ok(Uint8Array::from(content.as_slice()))
- }
-
- /// Release cached encrypted records held for playback read-ahead and seeks.
- pub fn close(&self) {
- self.closed.set(true);
- self.read_ahead.close();
- self.shared.chunk_cache().clear();
- }
-}
-
-impl Drop for BrowserFileReader {
- fn drop(&mut self) {
- self.read_ahead.close();
- }
-}
-
-impl BrowserFileReader {
- async fn read_range_inner(&self, start: usize, length: usize) -> Result, String> {
- if self.closed.get() {
- return Err("browser file reader is closed".to_string());
- }
- if length > MAX_BROWSER_RANGE_BYTES {
- return Err(format!(
- "browser range reads are limited to {MAX_BROWSER_RANGE_BYTES} bytes"
- ));
- }
- let lease = self.read_ahead.begin_read(start, length);
- let bytes = self
- .shared
- .data_download_range_with(&self.root_data_map, start, length, |address| {
- lease.record(address)
- })
- .await;
- if matches!(bytes, Err(crate::data::Error::Encryption(_))) {
- // The records do not decrypt as the DataMap declares, so reading
- // further ahead would only spend bandwidth and memory.
- self.read_ahead.close();
- }
- bytes
- .map(|bytes| bytes.to_vec())
- .map_err(|error| error.to_string())
- }
-}
-
#[derive(Default, Clone)]
struct UploadCheckpoint {
mode: PaymentMode,
@@ -2483,32 +2403,49 @@ impl BrowserNetworkClient {
serde_wasm_bindgen::to_value(&result).map_err(|error| JsValue::from_str(&error.to_string()))
}
- /// Download and reconstruct a complete public Autonomi file.
+ /// Download a public file into one JavaScript Uint8Array, using bounded
+ /// WASM buffers. `options` is `{ maxMemoryBytes?, signal? }`: the largest
+ /// output buffer to allocate, and an AbortSignal that cancels the download.
+ /// For disk-backed downloads use openPublicFile and reader.pipeTo(writable).
#[wasm_bindgen(js_name = downloadPublicFile)]
pub async fn download_public_file(
&self,
file: JsValue,
concurrency: Option,
on_progress: Option,
+ options: Option,
) -> Result {
let file: BrowserPublicFileInput = serde_wasm_bindgen::from_value(file)
.map_err(|error| JsValue::from_str(&error.to_string()))?;
- self.download_file(BrowserFileSource::Public(file), concurrency, on_progress)
- .await
+ self.download_file(
+ BrowserFileSource::Public(file),
+ concurrency,
+ on_progress,
+ options,
+ )
+ .await
}
- /// Download and reconstruct a private file from the DataMap its uploader kept.
+ /// Download a private file into one JavaScript Uint8Array. Takes the same
+ /// arguments as downloadPublicFile; openPrivateFile and pipeTo support
+ /// files that cannot fit in one JavaScript buffer.
#[wasm_bindgen(js_name = downloadPrivateFile)]
pub async fn download_private_file(
&self,
file: JsValue,
concurrency: Option,
on_progress: Option,
+ options: Option,
) -> Result {
let file: BrowserPrivateFileInput = serde_wasm_bindgen::from_value(file)
.map_err(|error| JsValue::from_str(&error.to_string()))?;
- self.download_file(BrowserFileSource::Private(file), concurrency, on_progress)
- .await
+ self.download_file(
+ BrowserFileSource::Private(file),
+ concurrency,
+ on_progress,
+ options,
+ )
+ .await
}
/// Resolve and validate a public file for random-access range reads.
@@ -2729,12 +2666,11 @@ impl BrowserNetworkClient {
source: BrowserFileSource,
concurrency: Option,
on_progress: Option,
+ options: Option,
) -> Result {
- let progress = ProgressReporter::from_js(on_progress);
- let result = self
- .download_file_inner(source, concurrency.unwrap_or(usize::MAX), &progress)
- .await
+ let settings = download::DownloadSettings::new(concurrency, on_progress, options)
.map_err(|error| JsValue::from_str(&error))?;
+ let result = self.download_file_inner(source, settings).await?;
serde_wasm_bindgen::to_value(&result).map_err(|error| JsValue::from_str(&error.to_string()))
}
@@ -2745,69 +2681,45 @@ impl BrowserNetworkClient {
options: BrowserFileReaderOptions,
) -> Result {
let resolved = self.resolve_file(source, &progress).await?;
- let file = resolved.file;
progress.report(&format!(
"Ready to stream {} ({} bytes, {} chunks)",
- file.name,
- file.size,
- file.chunks.len()
+ resolved.file.name,
+ resolved.file.size,
+ resolved.index.infos().len()
));
- let read_ahead = read_ahead::ReadAhead::new(
+ Ok(BrowserFileReader::new(
+ Rc::clone(&self.shared),
+ resolved,
&self.read_ahead,
- &resolved.root_data_map,
options.streaming,
- );
- Ok(BrowserFileReader {
- shared: Rc::clone(&self.shared),
- file,
- root_data_map: resolved.root_data_map,
- read_ahead,
- closed: Cell::new(false),
- })
+ ))
}
+ /// Errors are JavaScript values so an AbortSignal's reason reaches the caller.
async fn download_file_inner(
&self,
source: BrowserFileSource,
- concurrency: usize,
- progress: &ProgressReporter,
- ) -> Result {
- if concurrency == 0 {
- return Err("download concurrency must be a positive integer".to_string());
- }
- let mut resolved = self.resolve_file(source, progress).await?;
- let content = self
- .shared
- .data_download_with_progress(
- &resolved.root_data_map,
- concurrency,
- &|completed, total| {
- progress.report(&format!("Downloaded chunk {completed}/{total}"));
- },
- )
- .await
- .map_err(|error| error.to_string())?
- .to_vec();
- if content.len() != resolved.file.size {
- return Err(format!(
- "reconstructed file has {} bytes, expected {}",
- content.len(),
- resolved.file.size
- ));
- }
- let hash = hex::encode(blake3::hash(&content).as_bytes());
- if let Some(expected_hash) = resolved.expected_hash.as_ref() {
- super::verify_record(expected_hash, &content).map_err(|error| error.to_string())?;
- }
- resolved.file.blake3 = hash.clone();
- progress.report(&format!(
- "Verified complete {} as {hash}",
- resolved.file.name
- ));
+ settings: download::DownloadSettings,
+ ) -> Result {
+ // Validates the signal before any network work, and covers resolution.
+ let mut cancel = download::Cancellation::new(settings.signal.clone())?;
+ let resolved = cancel
+ .run(async {
+ self.resolve_file(source, &settings.progress)
+ .await
+ .map_err(|error| JsValue::from_str(&error))
+ })
+ .await?;
+ let (content, hash) =
+ download::collect(&self.shared, &resolved.index, &settings, &mut cancel).await?;
+ let file = download::completed_descriptor(resolved.file, &resolved.index, hash.clone());
+ settings
+ .progress
+ .report(&format!("Verified complete {} as {hash}", file.name));
Ok(BrowserDownloadResult {
content,
hash,
- file: resolved.file,
+ file,
data_map_node: resolved.data_map_node,
})
}
@@ -2910,32 +2822,24 @@ impl BrowserNetworkClient {
.await
.map_err(|error| error.to_string())?;
- let mut actual_chunks = super::chunk_infos(&root_data_map);
- actual_chunks.sort_by_key(|chunk| chunk.index);
- if actual_chunks.len() < 3 {
+ let index = self_encryption::DataMapIndex::new(&root_data_map)
+ .map_err(|error| error.to_string())?;
+ if index.infos().len() < crate::client_engine::files::MIN_FILE_CHUNKS {
return Err("ant-core returned an invalid public DataMap".to_string());
}
- let resolved_size = actual_chunks.iter().try_fold(0usize, |total, chunk| {
- total
- .checked_add(chunk.src_size)
- .ok_or_else(|| "resolved public file size overflow".to_string())
- })?;
- if !(self_encryption::MIN_ENCRYPTABLE_BYTES..=super::MAX_BROWSER_FILE_BYTES)
- .contains(&resolved_size)
- {
- return Err(format!("invalid public file size {resolved_size}"));
+ if index.file_size() > super::manifest::MAX_SAFE_JS_INTEGER {
+ return Err("file size exceeds JavaScript's exact integer range".into());
}
- file.size = resolved_size;
- file.chunks = actual_chunks;
+ file.size = index.file_size();
+ file.chunks = Vec::new(); // Listed from the index once the file is read.
file.data_map_size = encoded_data_map.len();
file.blake3.clear(); // Computed when plaintext is read; not a second content identity.
file.content_type = normalized_content_type(&file.content_type);
Ok(ResolvedBrowserFile {
file,
- expected_hash: None,
data_map_node: None,
- root_data_map,
+ index,
})
}
@@ -2977,7 +2881,7 @@ impl BrowserNetworkClient {
let descriptor = PublicFileDescriptor {
name: name.to_string(),
address: encrypted.address,
- size: content.len(),
+ size: content.len() as u64,
content_type: normalized_content_type(content_type),
blake3: encrypted.blake3,
data_map_size: encrypted.data_map_size,
@@ -3076,7 +2980,7 @@ impl BrowserNetworkClient {
let descriptor = PublicFileDescriptor {
name: staged.name,
address: staged.address,
- size: staged.size,
+ size: staged.size as u64,
content_type: staged.content_type,
blake3: staged.blake3,
data_map_size: staged.data_map_size,
diff --git a/ant-core/src/browser/wasm_transport/download.rs b/ant-core/src/browser/wasm_transport/download.rs
new file mode 100644
index 00000000..b989a9eb
--- /dev/null
+++ b/ant-core/src/browser/wasm_transport/download.rs
@@ -0,0 +1,592 @@
+//! Bounded plaintext reads with 64-bit positions and caller-owned destinations.
+use super::*;
+use crate::client_engine::files::ordered_pipeline;
+use bytes::Bytes;
+use self_encryption::DataMapIndex;
+use std::ops::Range;
+use web_sys::{AbortSignal, WritableStream, WritableStreamDefaultWriter};
+
+/// Plaintext a stream holds at once: chunks in flight, fetched or being
+/// written. Fetching continues during writes up to this bound.
+const STREAM_BUFFER_BYTES: u64 = 32 * 1024 * 1024;
+/// Plaintext a complete download copies back into WASM at a time to hash it.
+const HASH_PIECE_BYTES: u64 = 4 * 1024 * 1024;
+const STREAM_HINT: &str =
+ "use openPublicFile/openPrivateFile and reader.pipeTo(writable) to stream to disk";
+const CLOSED_READER: &str = "browser file reader is closed";
+const ABORTED: &str = "download aborted";
+const ABORT_EVENT: &str = "abort";
+const POSITIVE_CONCURRENCY: &str = "download concurrency must be a positive integer";
+const NOT_ABORT_SIGNAL: &str = "signal must be an AbortSignal";
+const NOT_WRITABLE_STREAM: &str = "destination must be a WritableStream";
+/// The output's constructor and view method, called through `Reflect` because
+/// the `js_sys` bindings take `u32` lengths and offsets.
+const UINT8_ARRAY: &str = "Uint8Array";
+const SUBARRAY: &str = "subarray";
+
+/// A nonnegative integer that JavaScript represents exactly.
+fn safe_integer(value: f64, label: &str) -> Result {
+ if value < 0.0 || !js_sys::Number::is_safe_integer(&JsValue::from_f64(value)) {
+ return Err(format!("{label} must be a nonnegative safe integer"));
+ }
+ Ok(value as u64)
+}
+
+fn js_string(error: impl std::fmt::Display) -> JsValue {
+ JsValue::from_str(&error.to_string())
+}
+
+/// Progress of a complete download, which startup probes parse.
+fn chunk_progress(written: usize, total: usize) -> String {
+ format!("Downloaded chunk {written}/{total}")
+}
+
+/// An optional options object; `undefined` and `null` select the defaults.
+pub(super) fn options_from_js(
+ value: Option,
+) -> Result {
+ match value {
+ Some(value) if !value.is_undefined() && !value.is_null() => {
+ serde_wasm_bindgen::from_value(value).map_err(|error| error.to_string())
+ }
+ _ => Ok(T::default()),
+ }
+}
+
+/// Release the writer even if the Rust future is dropped before it completes.
+struct Writer(WritableStreamDefaultWriter);
+impl Drop for Writer {
+ fn drop(&mut self) {
+ self.0.release_lock();
+ }
+}
+
+/// `pipeTo` options, modelled on `ReadableStream.pipeTo`.
+#[derive(Default, Deserialize)]
+#[serde(rename_all = "camelCase")]
+struct PipeOptions {
+ /// First byte to write.
+ start: Option,
+ /// Exclusive end of the written range; the file size by default.
+ end: Option,
+ /// AbortSignal that cancels this operation.
+ #[serde(default, with = "serde_wasm_bindgen::preserve")]
+ signal: JsValue,
+ /// Called with `(bytesWritten, totalBytes)` after each write.
+ #[serde(default, with = "serde_wasm_bindgen::preserve")]
+ on_progress: JsValue,
+}
+
+#[derive(Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+struct PipeResult {
+ bytes_written: u64,
+ hash: String,
+}
+
+/// Complete-download options: `{ maxMemoryBytes?, signal? }`.
+#[derive(Default, Deserialize)]
+#[serde(rename_all = "camelCase")]
+struct DownloadOptions {
+ /// Largest output buffer to allocate; larger files fail before transfer.
+ max_memory_bytes: Option,
+ /// AbortSignal that cancels the download.
+ #[serde(default, with = "serde_wasm_bindgen::preserve")]
+ signal: JsValue,
+}
+
+/// Validated complete-download arguments.
+pub(super) struct DownloadSettings {
+ concurrency: usize,
+ memory_budget: Option,
+ pub(super) progress: ProgressReporter,
+ /// AbortSignal, or `undefined` when the caller passed none.
+ pub(super) signal: JsValue,
+}
+
+impl DownloadSettings {
+ pub(super) fn new(
+ concurrency: Option,
+ on_progress: Option,
+ options: Option,
+ ) -> Result {
+ let concurrency = match concurrency {
+ None => usize::MAX,
+ Some(0) => return Err(POSITIVE_CONCURRENCY.into()),
+ Some(concurrency) => concurrency,
+ };
+ let options: DownloadOptions = options_from_js(options)?;
+ Ok(Self {
+ concurrency,
+ memory_budget: options
+ .max_memory_bytes
+ .map(|value| safe_integer(value, "memory budget"))
+ .transpose()?,
+ progress: ProgressReporter::from_js(on_progress),
+ signal: options.signal,
+ })
+ }
+}
+
+/// An AbortSignal's `abort` event. Detaches its listener when dropped.
+struct AbortListener {
+ signal: AbortSignal,
+ callback: Closure,
+ fired: oneshot::Receiver<()>,
+}
+
+impl AbortListener {
+ fn new(signal: JsValue) -> Result {
+ let signal = signal
+ .dyn_into::()
+ .map_err(|_| JsValue::from_str(NOT_ABORT_SIGNAL))?;
+ let (sender, fired) = oneshot::channel();
+ let mut sender = Some(sender);
+ let callback = Closure::::new(move || {
+ if let Some(sender) = sender.take() {
+ let _ = sender.send(());
+ }
+ });
+ signal.add_event_listener_with_callback(ABORT_EVENT, callback.as_ref().unchecked_ref())?;
+ Ok(Self {
+ signal,
+ callback,
+ fired,
+ })
+ }
+
+ /// The signal's abort reason, once it has aborted.
+ fn reason(&self) -> Option {
+ self.signal.aborted().then(|| {
+ let reason = self.signal.reason();
+ if reason.is_undefined() {
+ JsValue::from_str(ABORTED)
+ } else {
+ reason
+ }
+ })
+ }
+}
+
+impl Drop for AbortListener {
+ fn drop(&mut self) {
+ let _ = self.signal.remove_event_listener_with_callback(
+ ABORT_EVENT,
+ self.callback.as_ref().unchecked_ref(),
+ );
+ }
+}
+
+/// Stops an operation when its optional AbortSignal fires.
+pub(super) struct Cancellation(Option);
+
+impl Cancellation {
+ pub(super) fn new(signal: JsValue) -> Result {
+ if signal.is_undefined() || signal.is_null() {
+ return Ok(Self(None));
+ }
+ AbortListener::new(signal).map(|listener| Self(Some(listener)))
+ }
+
+ /// Fail with the abort reason once the signal has aborted.
+ fn check(&self) -> Result<(), JsValue> {
+ match self.0.as_ref().and_then(AbortListener::reason) {
+ Some(reason) => Err(reason),
+ None => Ok(()),
+ }
+ }
+
+ /// Run `operation` unless the signal aborts first. The signal is polled
+ /// before the operation, so an aborted operation is dropped, stopping its
+ /// fetches and retry waits, without running again.
+ pub(super) async fn run(
+ &mut self,
+ operation: impl Future>,
+ ) -> Result {
+ self.check()?;
+ let Some(abort) = self.0.as_mut() else {
+ return operation.await;
+ };
+ let finished = {
+ futures_util::pin_mut!(operation);
+ match select(&mut abort.fired, operation).await {
+ Either::Left(_) => None,
+ Either::Right((result, _)) => Some(result),
+ }
+ };
+ finished.unwrap_or_else(|| {
+ Err(self
+ .check()
+ .err()
+ .unwrap_or_else(|| JsValue::from_str(ABORTED)))
+ })
+ }
+}
+
+/// Fetch and decrypt `chunks` and hand each to `write` in file order. Fetching
+/// continues while a write is pending, within the client's adaptive fetch cap,
+/// until the chunks in flight, fetched and being written hold
+/// `STREAM_BUFFER_BYTES` of plaintext. Each missing record is retried on its
+/// own schedule, so retry waits overlap with the other fetches; a record
+/// waiting to retry still holds its place under the cap.
+async fn stream_chunks(
+ shared: &crate::data::Client,
+ index: &DataMapIndex,
+ chunks: Range,
+ write: W,
+) -> Result<(), JsValue>
+where
+ W: FnMut(usize, Bytes) -> WF,
+ WF: Future>,
+{
+ ordered_pipeline(
+ chunks,
+ |chunk| {
+ let span = index.chunk_range(chunk);
+ span.end - span.start
+ },
+ STREAM_BUFFER_BYTES,
+ &|| shared.controller().fetch.current(),
+ |chunk| async move {
+ shared
+ .data_download_indexed_chunk(index, chunk)
+ .await
+ .map_err(js_string)
+ },
+ write,
+ )
+ .await
+}
+
+/// Download a whole file into one JavaScript `Uint8Array`. Chunks are fetched
+/// as a complete download fetches them, in any order, and each is copied
+/// straight into place from WASM memory; the file is hashed afterwards. A
+/// caller can impose its own memory budget; allocation failures recommend the
+/// disk-backed path without downloading the file first.
+pub(super) async fn collect(
+ shared: &crate::data::Client,
+ index: &DataMapIndex,
+ settings: &DownloadSettings,
+ cancel: &mut Cancellation,
+) -> Result<(Uint8Array, String), JsValue> {
+ cancel.check()?;
+ let size = index.file_size();
+ if settings.memory_budget.is_some_and(|limit| size > limit) {
+ return Err(js_string(format_args!(
+ "file exceeds the download memory budget; {STREAM_HINT}"
+ )));
+ }
+ // Reflect calls preserve Number offsets above u32::MAX and catch JS
+ // allocation exceptions instead of turning them into WASM traps.
+ let constructor = js_sys::Reflect::get(&js_sys::global(), &JsValue::from_str(UINT8_ARRAY))?
+ .dyn_into::()?;
+ let output =
+ js_sys::Reflect::construct(&constructor, &Array::of1(&JsValue::from_f64(size as f64)))
+ .map_err(|error| {
+ js_string(format_args!(
+ "cannot allocate download buffer: {}; {STREAM_HINT}",
+ js_error_message(error)
+ ))
+ })?
+ .unchecked_into::();
+ let subarray = js_sys::Reflect::get(&output, &JsValue::from_str(SUBARRAY))?
+ .dyn_into::()?;
+ let view = |span: Range| {
+ subarray
+ .call2(
+ &output,
+ &JsValue::from_f64(span.start as f64),
+ &JsValue::from_f64(span.end as f64),
+ )
+ .map(|view| view.unchecked_into::())
+ };
+ let total = index.infos().len();
+ let written = Cell::new(0);
+ // The output's own error, which the caller receives instead of a message.
+ let output_error = RefCell::new(None);
+ settings.progress.report(&chunk_progress(0, total));
+ cancel
+ .run(async {
+ shared
+ .data_download_indexed_chunks(index, settings.concurrency, |chunk, plaintext| {
+ let placed = view(index.chunk_range(chunk)).map_err(|error| {
+ output_error.replace(Some(error.clone()));
+ js_error_message(error)
+ })?;
+ placed.copy_from(&plaintext);
+ written.set(written.get() + 1);
+ settings
+ .progress
+ .report(&chunk_progress(written.get(), total));
+ Ok(())
+ })
+ .await
+ .map_err(|error| output_error.take().unwrap_or_else(|| js_string(error)))
+ })
+ .await?;
+ let hash = output_hash(size, view)?;
+ Ok((output, hash))
+}
+
+/// BLAKE3 of a `size`-byte output, copied back into WASM through `view` in
+/// `HASH_PIECE_BYTES` pieces.
+fn output_hash(
+ size: u64,
+ view: impl Fn(Range) -> Result,
+) -> Result {
+ let mut hasher = blake3::Hasher::new();
+ let mut buffer = vec![0; size.min(HASH_PIECE_BYTES) as usize];
+ let mut start = 0;
+ while start < size {
+ let end = size.min(start + HASH_PIECE_BYTES);
+ let piece = &mut buffer[..(end - start) as usize];
+ view(start..end)?.copy_to(piece);
+ hasher.update(piece);
+ start = end;
+ }
+ Ok(hasher.finalize().to_hex().to_string())
+}
+
+/// The descriptor of a completely read file, with its chunk list and hash.
+pub(super) fn completed_descriptor(
+ mut file: PublicFileDescriptor,
+ index: &DataMapIndex,
+ hash: String,
+) -> PublicFileDescriptor {
+ file.chunks = index
+ .infos()
+ .iter()
+ .map(super::super::browser_chunk_info)
+ .collect();
+ file.blake3 = hash;
+ file
+}
+
+/// A validated `pipeTo` call.
+struct PipePlan {
+ range: Range,
+ progress: Option,
+ cancel: Cancellation,
+}
+
+/// Random-access file reader. Content memory is bounded independently of file
+/// size. The resolved chunk map and seek index remain resident in memory.
+#[wasm_bindgen(js_name = BrowserFileReader)]
+pub struct BrowserFileReader {
+ shared: Rc,
+ /// Descriptor without its chunk list; the index holds the chunk metadata.
+ file: PublicFileDescriptor,
+ index: Rc,
+ /// Fetches ahead of sequential range reads; see `read_ahead`.
+ pub(super) read_ahead: Rc,
+ closed: Cell,
+}
+
+#[wasm_bindgen(js_class = BrowserFileReader)]
+impl BrowserFileReader {
+ /// Exact plaintext byte count as a JavaScript safe integer.
+ #[wasm_bindgen(getter)]
+ pub fn size(&self) -> f64 {
+ self.file.size as f64
+ }
+
+ #[wasm_bindgen(getter, js_name = contentType)]
+ pub fn content_type(&self) -> String {
+ self.file.content_type.clone()
+ }
+
+ #[wasm_bindgen(getter)]
+ pub fn name(&self) -> String {
+ self.file.name.clone()
+ }
+
+ /// Read up to 4 MiB. Positions above 4 GiB are supported without truncation.
+ /// Fractions, negatives, and integers not exactly representable in JS fail.
+ #[wasm_bindgen(js_name = readRange)]
+ pub async fn read_range(&self, start: f64, length: f64) -> Result {
+ if self.closed.get() {
+ return Err(JsValue::from_str(CLOSED_READER));
+ }
+ let start = safe_integer(start, "range start").map_err(js_string)?;
+ let length = safe_integer(length, "range length").map_err(js_string)?;
+ if length > MAX_BROWSER_RANGE_BYTES as u64 {
+ return Err(JsValue::from_str(&format!(
+ "browser range reads are limited to {MAX_BROWSER_RANGE_BYTES} bytes"
+ )));
+ }
+ let lease = self.read_ahead.begin_read(start, length as usize);
+ let bytes = self
+ .shared
+ .data_download_indexed_range(&self.index, start, length as usize, |address| {
+ lease.record(address)
+ })
+ .await;
+ if matches!(bytes, Err(crate::data::Error::Encryption(_))) {
+ // The records do not decrypt as the DataMap declares, so reading
+ // further ahead would only spend bandwidth and memory.
+ self.read_ahead.close();
+ }
+ let bytes = bytes.map_err(js_string)?;
+ Ok(Uint8Array::from(bytes.as_ref()))
+ }
+
+ /// Write the file to a WritableStream (including a file-system writable).
+ /// `options` is `{ start?, end?, signal?, onProgress? }`: an optional
+ /// half-open byte range, an AbortSignal that cancels the operation, and a
+ /// `(bytesWritten, totalBytes)` callback run after each write.
+ ///
+ /// Chunks are fetched concurrently and written in order, at most 4 MiB per
+ /// write, each awaited before the next; fetching continues during writes
+ /// until 32 MiB of plaintext is held. Invalid calls reject without touching
+ /// the destination. Otherwise the destination is closed on success and
+ /// aborted on failure, and the writer lock is always released. An abort
+ /// while the destination is closing still rejects, but the destination may
+ /// already be committed. Returns the BLAKE3 and byte count of the written
+ /// range.
+ #[wasm_bindgen(js_name = pipeTo)]
+ pub async fn pipe_to(
+ &self,
+ writable: JsValue,
+ options: Option,
+ ) -> Result {
+ let plan = self.plan_pipe(options)?;
+ let writable = writable
+ .dyn_into::()
+ .map_err(|_| JsValue::from_str(NOT_WRITABLE_STREAM))?;
+ let writer = Writer(writable.get_writer()?);
+ let result = self.pipe(&writer.0, plan).await;
+ if let Err(error) = &result {
+ // Not awaited: an abort settles only once a stalled write does,
+ // and the rejection must not wait for that.
+ let settled = JsFuture::from(writer.0.abort_with_reason(error));
+ wasm_bindgen_futures::spawn_local(async move {
+ let _ = settled.await;
+ });
+ }
+ result
+ }
+
+ /// Close the reader and release the records its read-ahead holds. Later
+ /// calls fail; use an AbortSignal to cancel a pipeTo in progress. Records
+ /// in the client's shared cache stay; that cache is bounded and may serve
+ /// other readers.
+ pub fn close(&self) {
+ self.closed.set(true);
+ self.read_ahead.close();
+ }
+}
+
+impl Drop for BrowserFileReader {
+ fn drop(&mut self) {
+ self.read_ahead.close();
+ }
+}
+
+impl BrowserFileReader {
+ /// `streaming` treats every read as part of a sequential stream for
+ /// read-ahead, as media playback needs.
+ pub(super) fn new(
+ shared: Rc,
+ resolved: ResolvedBrowserFile,
+ read_ahead: &Rc,
+ streaming: bool,
+ ) -> Self {
+ let index = Rc::new(resolved.index);
+ Self {
+ shared,
+ file: resolved.file,
+ read_ahead: read_ahead::ReadAhead::new(read_ahead, Rc::clone(&index), streaming),
+ index,
+ closed: Cell::new(false),
+ }
+ }
+
+ /// Validate a `pipeTo` call before it touches the destination.
+ fn plan_pipe(&self, options: Option) -> Result {
+ if self.closed.get() {
+ return Err(JsValue::from_str(CLOSED_READER));
+ }
+ let options: PipeOptions = options_from_js(options).map_err(js_string)?;
+ let progress = if options.on_progress.is_undefined() || options.on_progress.is_null() {
+ None
+ } else {
+ Some(
+ options
+ .on_progress
+ .dyn_into::()
+ .map_err(|_| JsValue::from_str("onProgress must be a function"))?,
+ )
+ };
+ let start =
+ safe_integer(options.start.unwrap_or(0.0), "stream start").map_err(js_string)?;
+ let end = options
+ .end
+ .map(|end| safe_integer(end, "stream end"))
+ .transpose()
+ .map_err(js_string)?
+ .unwrap_or(self.file.size);
+ if start > end || end > self.file.size {
+ return Err(JsValue::from_str("stream range is outside the file"));
+ }
+ Ok(PipePlan {
+ range: start..end,
+ progress,
+ cancel: Cancellation::new(options.signal)?,
+ })
+ }
+
+ async fn pipe(
+ &self,
+ writer: &WritableStreamDefaultWriter,
+ plan: PipePlan,
+ ) -> Result {
+ let PipePlan {
+ range,
+ progress,
+ mut cancel,
+ } = plan;
+ let progress = &progress;
+ let total = range.end - range.start;
+ let mut hasher = blake3::Hasher::new();
+ cancel
+ .run(async {
+ stream_chunks(
+ &self.shared,
+ &self.index,
+ self.index.chunks_overlapping(range.clone()),
+ |chunk, plaintext| {
+ let span = self.index.chunk_range(chunk);
+ let from = range.start.max(span.start);
+ let to = range.end.min(span.end);
+ let plaintext = plaintext
+ .slice((from - span.start) as usize..(to - span.start) as usize);
+ hasher.update(&plaintext);
+ let mut written = from - range.start;
+ async move {
+ for piece in plaintext.chunks(MAX_BROWSER_RANGE_BYTES) {
+ JsFuture::from(writer.write_with_chunk(&Uint8Array::from(piece)))
+ .await?;
+ written += piece.len() as u64;
+ if let Some(callback) = progress {
+ callback.call2(
+ &JsValue::NULL,
+ &JsValue::from_f64(written as f64),
+ &JsValue::from_f64(total as f64),
+ )?;
+ }
+ }
+ Ok(())
+ }
+ },
+ )
+ .await?;
+ JsFuture::from(writer.close()).await.map(drop)
+ })
+ .await?;
+ serde_wasm_bindgen::to_value(&PipeResult {
+ bytes_written: total,
+ hash: hasher.finalize().to_hex().to_string(),
+ })
+ .map_err(js_string)
+ }
+}
diff --git a/ant-core/src/browser/wasm_transport/read_ahead.rs b/ant-core/src/browser/wasm_transport/read_ahead.rs
index a61ec3ee..026204e1 100644
--- a/ant-core/src/browser/wasm_transport/read_ahead.rs
+++ b/ant-core/src/browser/wasm_transport/read_ahead.rs
@@ -15,13 +15,12 @@
//! read waited for inform the reads' adaptive concurrency, and read-ahead keeps
//! its records out of the shared chunk cache.
use super::{BrowserNetworkCore, SharedNetworkAdapter};
-use crate::client_engine::files::RecordLayout;
-use crate::client_engine::read_ahead::releasable;
+use crate::client_engine::read_ahead::{read_ahead_window, releasable};
use crate::client_engine::read_budget::ReadBudget;
use crate::data::{ChunkCache, Client, ClientConfig, Error, Network};
use bytes::Bytes;
use futures::future::{AbortHandle, Abortable, FutureExt, LocalBoxFuture, Shared};
-use self_encryption::{DataMap, MAX_CHUNK_SIZE};
+use self_encryption::{DataMapIndex, MAX_CHUNK_SIZE};
use std::cell::{Cell, RefCell};
use std::collections::{BTreeMap, HashMap, VecDeque};
use std::ops::Range;
@@ -207,13 +206,14 @@ impl ReadAheadPool {
/// Read-ahead of one file reader.
pub(super) struct ReadAhead {
pool: Rc,
- layout: RecordLayout,
+ /// The reader's index of the file, shared with it.
+ layout: Rc,
/// Every read starts a sequential stream, as media playback's reads do.
streaming: bool,
/// Ends of recent reads; a read starting at one continues it.
- recent_ends: RefCell>,
+ recent_ends: RefCell>,
/// Start of the latest sequential read; the read-ahead window starts here.
- anchor: Cell>,
+ anchor: Cell >,
/// Records of each read in progress, by read id. Like the window, they are
/// never cancelled or released.
reads: RefCell>>,
@@ -228,14 +228,13 @@ pub(super) struct ReadAhead {
}
impl ReadAhead {
- /// Read-ahead for one reader of `root`. A DataMap whose layout range reads
- /// reject gets read-ahead that never fetches, so the reader still opens and
- /// its reads report the error.
- pub(super) fn new(pool: &Rc, root: &DataMap, streaming: bool) -> Rc {
- let (layout, closed) = match RecordLayout::new(root) {
- Ok(layout) => (layout, false),
- Err(_) => (RecordLayout::default(), true),
- };
+ /// Read-ahead for one reader of the file `layout` indexes. Positions are
+ /// 64-bit, so read-ahead follows reads past 4 GiB on every platform.
+ pub(super) fn new(
+ pool: &Rc,
+ layout: Rc,
+ streaming: bool,
+ ) -> Rc {
let reader = Rc::new(Self {
pool: Rc::clone(pool),
layout,
@@ -247,7 +246,7 @@ impl ReadAhead {
last_read: Cell::new(Instant::now()),
slots: RefCell::default(),
next_id: Cell::new(0),
- closed: Cell::new(closed),
+ closed: Cell::new(false),
});
pool.readers.borrow_mut().push(Rc::downgrade(&reader));
reader
@@ -263,8 +262,10 @@ impl ReadAhead {
/// the start of the file also fetches the last record, where containers such
/// as MP4 and WebM often keep the index a player reads next. A read that
/// needs no records, such as one of zero length, changes nothing.
- pub(super) fn begin_read(self: &Rc, start: usize, length: usize) -> ReadLease {
- let needed = self.layout.overlapping(start, length);
+ pub(super) fn begin_read(self: &Rc, start: u64, length: usize) -> ReadLease {
+ let needed = self
+ .layout
+ .chunks_overlapping(start..start.saturating_add(length as u64));
if self.closed.get() || needed.is_empty() {
return ReadLease {
read_ahead: Rc::clone(self),
@@ -276,7 +277,7 @@ impl ReadAhead {
let read = self.next_id();
let addresses = needed
.clone()
- .map(|index| self.layout.address(index))
+ .map(|index| self.layout.infos()[index].dst_hash.0)
.collect::>();
let indices = needed
.clone()
@@ -309,11 +310,11 @@ impl ReadAhead {
}
if sequential {
self.fill();
- } else if needed.end < self.layout.len() {
+ } else if needed.end < self.layout.infos().len() {
self.prefetch(needed.end);
}
if self.streaming && start == 0 {
- if let Some(last) = self.layout.len().checked_sub(1) {
+ if let Some(last) = self.layout.infos().len().checked_sub(1) {
self.prefetch(last);
}
}
@@ -322,7 +323,7 @@ impl ReadAhead {
if recent.len() == RECENT_READS {
recent.pop_front();
}
- recent.push_back(start.saturating_add(length));
+ recent.push_back(start.saturating_add(length as u64));
}
ReadLease {
read_ahead: Rc::clone(self),
@@ -357,8 +358,7 @@ impl ReadAhead {
fn window(&self) -> Range {
self.anchor.get().map_or(0..0, |anchor| {
- self.layout
- .window(anchor, READ_AHEAD_BYTES, MAX_WINDOW_RECORDS)
+ read_ahead_window(&self.layout, anchor, READ_AHEAD_BYTES, MAX_WINDOW_RECORDS)
})
}
@@ -426,7 +426,7 @@ impl ReadAhead {
}
let id = self.next_id();
let (abort, registration) = AbortHandle::new_pair();
- let address = self.layout.address(index);
+ let address = self.layout.infos()[index].dst_hash.0;
let this = Rc::clone(self);
let fetch = async move {
let result = Abortable::new(this.pool.fetch(address), registration).await;
diff --git a/ant-core/src/client_engine/files.rs b/ant-core/src/client_engine/files.rs
index a32d38bd..a830ed3d 100644
--- a/ant-core/src/client_engine/files.rs
+++ b/ant-core/src/client_engine/files.rs
@@ -2,9 +2,16 @@
//! filesystem or JS dependencies. Cryptography and recursive map semantics stay
//! in self_encryption, the same implementation used by the native client.
use bytes::Bytes;
+#[cfg(any(all(feature = "browser-wasm", target_arch = "wasm32"), test))]
+use futures_util::future::{select, Either};
+#[cfg(any(all(feature = "browser-wasm", target_arch = "wasm32"), test))]
+use futures_util::stream::FuturesUnordered;
use futures_util::StreamExt;
-use self_encryption::{DataMap, EncryptedChunk, XorName};
-use std::{cell::RefCell, collections::HashMap, future::Future, ops::Range};
+use self_encryption::{DataMap, DataMapIndex, EncryptedChunk};
+use std::{cell::RefCell, collections::HashMap, future::Future, ops::Range, sync::Mutex};
+
+/// self_encryption splits every encryptable file into at least three chunks.
+pub(crate) const MIN_FILE_CHUNKS: usize = 3;
pub(crate) type RecordRequest = (usize, [u8; 32]);
@@ -134,91 +141,82 @@ where
.enumerate()
.map(|(index, info)| (index, info.dst_hash.0))
.collect();
- let chunks = fetch_records_deferred(requests, fetch, cap, sleep, retryable)
- .await?
- .into_iter()
- .map(|(_, content)| EncryptedChunk { content })
- .collect::>();
+ let chunks =
+ fetch_records_deferred(requests, fetch, cap, sleep, retryable, |_, bytes| Ok(bytes))
+ .await?
+ .into_iter()
+ .map(|(_, content)| EncryptedChunk { content })
+ .collect::>();
self_encryption::decrypt(&root, &chunks).map_err(|e| ReadError::Invalid(e.to_string()))
}
-/// Plaintext layout of a resolved root DataMap, in record order. Chunk sizes are
-/// read from the native DataMap; checked sums avoid overflow on untrusted maps.
-#[derive(Default)]
-pub(crate) struct RecordLayout {
- /// Plaintext end offset and content address of each record.
- records: Vec<(usize, [u8; 32])>,
-}
-
-impl RecordLayout {
- pub(crate) fn new(map: &DataMap) -> Result {
- if map.is_child() {
- return Err("range reads require a resolved root DataMap".into());
- }
- let mut infos = map.infos().to_vec();
- infos.sort_by_key(|info| info.index);
- let mut end = 0usize;
- let mut records = Vec::with_capacity(infos.len());
- for (index, info) in infos.into_iter().enumerate() {
- if info.index != index {
- return Err("DataMap chunk indices must be contiguous".into());
- }
- end = end
- .checked_add(info.src_size)
- .ok_or("DataMap plaintext size overflow")?;
- records.push((end, info.dst_hash.0));
- }
- Ok(Self { records })
- }
-
- pub(crate) fn len(&self) -> usize {
- self.records.len()
- }
-
- /// Plaintext size of the file.
- pub(crate) fn size(&self) -> usize {
- self.records.last().map_or(0, |(end, _)| *end)
- }
-
- pub(crate) fn address(&self, index: usize) -> [u8; 32] {
- self.records[index].1
- }
-
- /// Index of the record holding plaintext byte `offset`; `len()` at or past EOF.
- pub(crate) fn record_at(&self, offset: usize) -> usize {
- self.records.partition_point(|(end, _)| *end <= offset)
- }
-
- /// Records overlapping the plaintext range `[start, start + length)`.
- pub(crate) fn overlapping(&self, start: usize, length: usize) -> Range {
- let first = self.record_at(start);
- if length == 0 {
- return first..first;
- }
- let last = self.record_at(start.saturating_add(length - 1));
- first..(last + 1).min(self.len())
- }
-}
-
-/// Half-open plaintext ranges. EOF and zero-length reads have the same
-/// semantics on every platform.
-pub(crate) fn range_records(
- map: &DataMap,
- start: usize,
- length: usize,
-) -> Result<(usize, Vec), String> {
- let layout = RecordLayout::new(map)?;
- let records = layout
- .overlapping(start, length)
- .map(|index| (index, layout.address(index)))
+/// Fetch, verify and decrypt `chunks` in one deferred retry pass, handing each
+/// plaintext chunk to `deliver` as it arrives, in any order. Nothing is kept
+/// once delivered, so memory is bounded by the fetches in flight.
+pub(crate) async fn read_chunks(
+ index: &DataMapIndex,
+ chunks: Range,
+ fetch: &F,
+ cap: &C,
+ sleep: &S,
+ retryable: fn(&E) -> bool,
+ deliver: D,
+) -> Result<(), ReadError>
+where
+ F: Fn([u8; 32]) -> Fut,
+ Fut: Future>,
+ C: Fn() -> usize,
+ S: Fn(std::time::Duration) -> SF,
+ SF: Future,
+ D: Fn(usize, Bytes) -> Result<(), String>,
+{
+ let requests = index.infos()[chunks]
+ .iter()
+ .map(|info| (info.index, info.dst_hash.0))
.collect();
- let end = start.saturating_add(length).min(layout.size());
- Ok((end.saturating_sub(start), records))
+ fetch_records_deferred(
+ requests,
+ fetch,
+ cap,
+ sleep,
+ retryable,
+ |chunk, encrypted| {
+ let plaintext = index
+ .decrypt_chunk(chunk, &encrypted)
+ .map_err(|e| e.to_string())?;
+ deliver(chunk, plaintext)?;
+ Ok(Bytes::new())
+ },
+ )
+ .await
+ .map(drop)
}
pub(crate) async fn read_range(
root: &DataMap,
- start: usize,
+ start: u64,
+ length: usize,
+ fetch: &F,
+ cap: &C,
+ sleep: &S,
+ retryable: fn(&E) -> bool,
+) -> Result>
+where
+ F: Fn([u8; 32]) -> Fut,
+ Fut: Future>,
+ C: Fn() -> usize,
+ S: Fn(std::time::Duration) -> SF,
+ SF: Future,
+{
+ let index = DataMapIndex::new(root).map_err(|e| ReadError::Invalid(e.to_string()))?;
+ read_indexed_range(&index, start, length, fetch, cap, sleep, retryable).await
+}
+
+/// Half-open plaintext range. EOF and zero-length reads have the same
+/// semantics on every platform.
+pub(crate) async fn read_indexed_range(
+ index: &DataMapIndex,
+ start: u64,
length: usize,
fetch: &F,
cap: &C,
@@ -232,39 +230,121 @@ where
S: Fn(std::time::Duration) -> SF,
SF: Future,
{
- let (length, required) = range_records(root, start, length).map_err(ReadError::Invalid)?;
- if length == 0 {
+ let end = start.saturating_add(length as u64).min(index.file_size());
+ if start >= end {
return Ok(Bytes::new());
}
- let records = fetch_records_deferred(required.clone(), fetch, cap, sleep, retryable).await?;
- let available: HashMap<_, _> = records.into_iter().collect();
- let fetch_cached = |batch: &[(usize, XorName)]| {
- batch
- .iter()
- .map(|(index, _)| {
- available
- .get(index)
- .cloned()
- .map(|content| (*index, content))
- .ok_or_else(|| {
- self_encryption::Error::Generic(format!("range omitted chunk {index}"))
- })
- })
- .collect()
- };
- let stream =
- self_encryption::streaming_decrypt_with_batch_size(root, fetch_cached, required.len())
- .map_err(|e| ReadError::Invalid(e.to_string()))?;
- let bytes = stream
- .get_range(start, length)
- .map_err(|e| ReadError::Invalid(e.to_string()))?;
- if bytes.len() != length {
- return Err(ReadError::Invalid(format!(
- "range returned {} bytes, expected {length}",
- bytes.len()
- )));
+ // `end - start` is at most the requested usize length.
+ let length = (end - start) as usize;
+ let mut output = Vec::new();
+ output
+ .try_reserve_exact(length)
+ .map_err(|e| ReadError::Invalid(format!("cannot allocate range: {e}")))?;
+ output.resize(length, 0);
+ let output = Mutex::new(output);
+ read_chunks(
+ index,
+ index.chunks_overlapping(start..end),
+ fetch,
+ cap,
+ sleep,
+ retryable,
+ |chunk, plaintext| {
+ let span = index.chunk_range(chunk);
+ let (from, to) = (start.max(span.start), end.min(span.end));
+ output.lock().expect("range output lock")
+ [(from - start) as usize..(to - start) as usize]
+ .copy_from_slice(
+ &plaintext[(from - span.start) as usize..(to - span.start) as usize],
+ );
+ Ok(())
+ },
+ )
+ .await?;
+ Ok(Bytes::from(output.into_inner().expect("range output lock")))
+}
+
+#[cfg(any(all(feature = "browser-wasm", target_arch = "wasm32"), test))]
+enum PipelineEvent {
+ Written(Result<(), X>),
+ Fetched(usize, Result),
+}
+
+/// Fetch `items` concurrently and hand each result to `write` in item order.
+/// Items launch in order while fewer than `cap()` are in flight and the cost
+/// of launched-but-unwritten items stays within `budget`; one item can always
+/// run. Fetching continues while a write is pending, so slow items and their
+/// retry waits overlap with the other items the cap and budget admit. An item
+/// waiting to retry still holds its place under the cap.
+#[cfg(any(all(feature = "browser-wasm", target_arch = "wasm32"), test))]
+pub(crate) async fn ordered_pipeline(
+ items: Range,
+ cost: impl Fn(usize) -> u64,
+ budget: u64,
+ cap: &C,
+ fetch: F,
+ mut write: W,
+) -> Result<(), X>
+where
+ F: Fn(usize) -> FF,
+ FF: Future>,
+ W: FnMut(usize, T) -> WF,
+ WF: Future>,
+ C: Fn() -> usize,
+{
+ let fetch = &fetch;
+ let mut in_flight = FuturesUnordered::new();
+ let mut ready = HashMap::new();
+ let mut writing = None;
+ let (mut next_launch, mut next_write) = (items.start, items.start);
+ let mut outstanding = 0u64;
+ while next_write < items.end {
+ while next_launch < items.end
+ && in_flight.len() < cap().max(1)
+ && (outstanding == 0 || outstanding.saturating_add(cost(next_launch)) <= budget)
+ {
+ let item = next_launch;
+ in_flight.push(async move { (item, fetch(item).await) });
+ outstanding = outstanding.saturating_add(cost(item));
+ next_launch += 1;
+ }
+ if writing.is_none() {
+ if let Some(value) = ready.remove(&next_write) {
+ writing = Some(Box::pin(write(next_write, value)));
+ }
+ }
+ // `outstanding` covers the next item to write, so with nothing being
+ // written that item is in flight.
+ let event = match writing.as_mut() {
+ Some(pending) if in_flight.is_empty() => PipelineEvent::Written(pending.await),
+ Some(pending) => match select(pending, in_flight.next()).await {
+ Either::Left((written, _)) => PipelineEvent::Written(written),
+ Either::Right((fetched, _)) => {
+ let (item, value) = fetched.expect("items are in flight");
+ PipelineEvent::Fetched(item, value)
+ }
+ },
+ None => {
+ let (item, value) = in_flight
+ .next()
+ .await
+ .expect("the next item to write is in flight");
+ PipelineEvent::Fetched(item, value)
+ }
+ };
+ match event {
+ PipelineEvent::Written(written) => {
+ written?;
+ writing = None;
+ outstanding -= cost(next_write);
+ next_write += 1;
+ }
+ PipelineEvent::Fetched(item, value) => {
+ ready.insert(item, value?);
+ }
+ }
}
- Ok(bytes)
+ Ok(())
}
/// Native file-download retry rounds: retry missing records together after the
@@ -313,12 +393,15 @@ where
Ok(results)
}
-async fn fetch_records_deferred(
+/// Fetch and verify records in deferred retry rounds. `accept` turns each
+/// verified record into the bytes kept for it, or rejects it as invalid.
+async fn fetch_records_deferred(
requests: Vec,
fetch: &F,
cap: &C,
sleep: &S,
retryable: fn(&E) -> bool,
+ accept: A,
) -> Result, ReadError>
where
F: Fn([u8; 32]) -> Fut,
@@ -326,18 +409,20 @@ where
C: Fn() -> usize,
S: Fn(std::time::Duration) -> SF,
SF: Future,
+ A: Fn(usize, Bytes) -> Result,
{
// Preserve the adapter's final typed fetch error across deferred rounds.
- let errors = std::sync::Mutex::new(HashMap::new());
+ let errors = Mutex::new(HashMap::new());
deferred_batch(
requests,
|index, address, _| {
- let errors = &errors;
+ let (errors, accept) = (&errors, &accept);
async move {
match fetch(address).await {
Ok(bytes) => {
crate::record::verify(&address, &bytes).map_err(ReadError::Invalid)?;
- Ok((index, Ok(bytes)))
+ let kept = accept(index, bytes).map_err(ReadError::Invalid)?;
+ Ok((index, Ok(kept)))
}
Err(error) if !retryable(&error) => Err(ReadError::Fetch(error)),
Err(error) => {
@@ -368,7 +453,9 @@ where
#[cfg(test)]
mod tests {
use super::*;
- use std::sync::{Arc, Mutex};
+
+ /// Long enough that only a stalled pipeline reaches it.
+ const STALL_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(5);
fn fixture() -> (Bytes, DataMap, HashMap<[u8; 32], Bytes>) {
let content = Bytes::from((0..18000).map(|i| (i * 37) as u8).collect::>());
@@ -454,27 +541,38 @@ mod tests {
(usize::MAX, 5),
(0, 0),
] {
- let seen = Mutex::new(Vec::new());
+ let seen = std::sync::Mutex::new(Vec::new());
let fetch = |address| {
seen.lock().unwrap().push(address);
let bytes = records[&address].clone();
async move { Ok::<_, String>(bytes) }
};
- let actual = read_range(&map, start, length, &fetch, &|| 3, &|_| async {}, |_| true)
- .await
- .unwrap();
+ let actual = read_range(
+ &map,
+ start as u64,
+ length,
+ &fetch,
+ &|| 3,
+ &|_| async {},
+ |_| true,
+ )
+ .await
+ .unwrap();
let expected =
&content[start.min(content.len())..start.saturating_add(length).min(content.len())];
assert_eq!(actual.as_ref(), expected);
- let (_, required) = range_records(&map, start, length).unwrap();
+ let end = (start as u64).saturating_add(length as u64);
+ let required = DataMapIndex::new(&map)
+ .unwrap()
+ .chunks_overlapping(start as u64..end);
assert_eq!(seen.lock().unwrap().len(), required.len());
}
}
#[tokio::test]
async fn deferred_rounds_retry_only_missing_records_and_preserve_order() {
- let attempts = Arc::new(Mutex::new(Vec::new()));
- let sleeps = Mutex::new(Vec::new());
+ let attempts = std::sync::Mutex::new(Vec::new());
+ let sleeps = std::sync::Mutex::new(Vec::new());
let result = deferred_batch(
vec![(0, 0u8), (1, 1), (2, 2)],
|index, key, attempt| {
@@ -576,36 +674,413 @@ mod tests {
assert_eq!(calls.load(std::sync::atomic::Ordering::Relaxed), 1);
}
- #[test]
- fn layout_maps_plaintext_ranges_to_records() {
- let infos = [10, 10, 10]
- .into_iter()
- .enumerate()
- .map(|(index, src_size)| self_encryption::ChunkInfo {
- index,
- dst_hash: XorName([index as u8 + 1; 32]),
- src_hash: XorName([0; 32]),
- src_size,
- })
- .collect();
- let layout = RecordLayout::new(&DataMap::new(infos)).unwrap();
- assert_eq!(layout.size(), 30);
- assert_eq!(layout.overlapping(0, 10), 0..1);
- assert_eq!(layout.overlapping(9, 2), 0..2);
- assert_eq!(layout.overlapping(10, 25), 1..3);
- assert_eq!(layout.overlapping(25, 0), 2..2);
- assert_eq!(layout.overlapping(30, 10), 3..3);
- assert_eq!(layout.address(1), [2; 32]);
+ #[tokio::test]
+ async fn malformed_maps_fail_range_reads() {
+ let (_, map, records) = fixture();
+ let fetch = |address| {
+ let bytes = records[&address].clone();
+ async move { Ok::<_, String>(bytes) }
+ };
+ let mut repeated = map.infos().to_vec();
+ repeated[1].index = 0;
+ let too_few = map.infos()[..MIN_FILE_CHUNKS - 1].to_vec();
+ for infos in [repeated, too_few] {
+ let error = read_range(
+ &DataMap::new(infos),
+ 0,
+ 1,
+ &fetch,
+ &|| 1,
+ &|_| async {},
+ |_| true,
+ )
+ .await
+ .unwrap_err();
+ assert!(matches!(error, ReadError::Invalid(_)));
+ }
}
- #[test]
- fn malformed_range_maps_are_rejected() {
- let (_, map, _) = fixture();
- let mut infos = map.infos().to_vec();
- infos[1].index = 0;
- assert!(range_records(&DataMap::new(infos), 0, 1).is_err());
+ #[tokio::test]
+ async fn altered_range_records_are_rejected() {
+ let (_, map, records) = fixture();
+ let fetch = |address| {
+ let mut bytes = records[&address].to_vec();
+ *bytes.last_mut().unwrap() ^= 1;
+ async move { Ok::<_, String>(Bytes::from(bytes)) }
+ };
+ let error = read_range(&map, 0, 1, &fetch, &|| 1, &|_| async {}, |_| true)
+ .await
+ .unwrap_err();
+ assert!(
+ matches!(error, ReadError::Invalid(message) if message.contains("BLAKE3 mismatch"))
+ );
+ }
+
+ #[tokio::test]
+ async fn a_missing_chunk_is_retried_on_its_own_schedule() {
+ let (content, map, records) = fixture();
+ let index = DataMapIndex::new(&map).unwrap();
+ let attempts = std::cell::Cell::new(0);
+ let sleeps = std::cell::RefCell::new(Vec::new());
+ let fetch_after = |available_from: usize| {
+ let (attempts, records) = (&attempts, &records);
+ move |address: [u8; 32]| {
+ attempts.set(attempts.get() + 1);
+ let found = attempts.get() >= available_from;
+ let bytes = records[&address].clone();
+ async move {
+ if found {
+ Ok(bytes)
+ } else {
+ Err("missing".to_string())
+ }
+ }
+ }
+ };
+ let sleep = |delay: std::time::Duration| {
+ sleeps.borrow_mut().push(delay.as_secs());
+ async {}
+ };
+ // The first pass and three deferred retries.
+ const ATTEMPTS: usize = 4;
+ // One chunk on its own, as each pipeTo fetch is.
+ let chunks = std::cell::RefCell::new(Vec::new());
+ let deliver = |chunk, plaintext| {
+ chunks.borrow_mut().push((chunk, plaintext));
+ Ok(())
+ };
+ read_chunks(
+ &index,
+ 1..2,
+ &fetch_after(ATTEMPTS),
+ &|| 1,
+ &sleep,
+ |_| true,
+ deliver,
+ )
+ .await
+ .unwrap();
+ let span = index.chunk_range(1);
+ assert_eq!(
+ *chunks.borrow(),
+ vec![(1, content.slice(span.start as usize..span.end as usize))]
+ );
+ assert_eq!(*sleeps.borrow(), vec![15, 45]);
+
+ attempts.set(0);
+ let error = read_chunks(
+ &index,
+ 1..2,
+ &fetch_after(ATTEMPTS + 1),
+ &|| 1,
+ &sleep,
+ |_| true,
+ deliver,
+ )
+ .await
+ .unwrap_err();
+ assert!(matches!(error, ReadError::Fetch(message) if message == "missing"));
+ assert_eq!(attempts.get(), ATTEMPTS);
+
+ attempts.set(0);
+ let error = read_chunks(
+ &index,
+ 1..2,
+ &fetch_after(ATTEMPTS + 1),
+ &|| 1,
+ &sleep,
+ |_| false,
+ deliver,
+ )
+ .await
+ .unwrap_err();
+ assert!(matches!(error, ReadError::Fetch(_)));
+ assert_eq!(attempts.get(), 1);
+ }
+
+ #[tokio::test]
+ async fn chunks_share_one_retry_pass() {
+ let (content, map, records) = fixture();
+ let index = DataMapIndex::new(&map).unwrap();
+ let attempts = std::sync::Mutex::new(HashMap::<[u8; 32], usize>::new());
+ let in_flight = std::cell::Cell::new(0);
+ let most_in_flight = std::cell::Cell::new(0);
+ let sleeps = std::sync::Mutex::new(Vec::new());
+ // The first and last records are missing until their third attempt.
+ let missing = [
+ index.infos()[0].dst_hash.0,
+ index.infos()[MIN_FILE_CHUNKS - 1].dst_hash.0,
+ ];
+ let fetch = |address: [u8; 32]| {
+ let attempt = {
+ let mut attempts = attempts.lock().unwrap();
+ let attempt = attempts.entry(address).or_default();
+ *attempt += 1;
+ *attempt
+ };
+ let bytes = records[&address].clone();
+ let (in_flight, most_in_flight) = (&in_flight, &most_in_flight);
+ async move {
+ in_flight.set(in_flight.get() + 1);
+ most_in_flight.set(most_in_flight.get().max(in_flight.get()));
+ tokio::task::yield_now().await;
+ in_flight.set(in_flight.get() - 1);
+ if missing.contains(&address) && attempt < 3 {
+ Err("missing".to_string())
+ } else {
+ Ok(bytes)
+ }
+ }
+ };
+ let received = std::cell::RefCell::new(Vec::new());
+ read_chunks(
+ &index,
+ 0..index.infos().len(),
+ &fetch,
+ &|| MIN_FILE_CHUNKS,
+ &|delay| {
+ sleeps.lock().unwrap().push(delay.as_secs());
+ async {}
+ },
+ |_| true,
+ |chunk, plaintext| {
+ received.borrow_mut().push((chunk, plaintext));
+ Ok(())
+ },
+ )
+ .await
+ .unwrap();
+ assert_eq!(most_in_flight.get(), MIN_FILE_CHUNKS);
+ // Both missing records wait out the same 15-second round.
+ assert_eq!(*sleeps.lock().unwrap(), vec![15]);
+ let mut received = received.into_inner();
+ received.sort_by_key(|(chunk, _)| *chunk);
+ assert_eq!(
+ received.iter().map(|(chunk, _)| *chunk).collect::>(),
+ (0..MIN_FILE_CHUNKS).collect::>()
+ );
+ for (chunk, plaintext) in received {
+ let span = index.chunk_range(chunk);
+ assert_eq!(
+ plaintext,
+ content.slice(span.start as usize..span.end as usize)
+ );
+ }
+ }
+
+ #[tokio::test]
+ async fn ranges_reject_mismatched_plaintext_size() {
+ let (_, map, records) = fixture();
let mut infos = map.infos().to_vec();
- infos[0].src_size = usize::MAX;
- assert!(range_records(&DataMap::new(infos), 0, 1).is_err());
+ infos[0].src_size += 1;
+ let fetch = |address| {
+ let bytes = records[&address].clone();
+ async move { Ok::<_, String>(bytes) }
+ };
+ let error = read_range(
+ &DataMap::new(infos),
+ 0,
+ 1,
+ &fetch,
+ &|| 1,
+ &|_| async {},
+ |_| true,
+ )
+ .await
+ .unwrap_err();
+ assert!(error.to_string().contains("the DataMap declares"));
+ }
+
+ #[tokio::test]
+ async fn pipeline_writes_in_order_within_its_budget() {
+ const ITEMS: usize = 6;
+ const COST: u64 = 10;
+ const BUDGET: u64 = 3 * COST;
+ let launched = std::cell::Cell::new(0u64);
+ let most_outstanding = std::cell::Cell::new(0u64);
+ let mut written = Vec::new();
+ ordered_pipeline(
+ 0..ITEMS,
+ |_| COST,
+ BUDGET,
+ &|| ITEMS,
+ |item| {
+ launched.set(launched.get() + 1);
+ async move {
+ // Later items finish first.
+ for _ in item..ITEMS {
+ tokio::task::yield_now().await;
+ }
+ Ok::<_, String>(item)
+ }
+ },
+ |item, value| {
+ assert_eq!(item, value);
+ let outstanding = (launched.get() - written.len() as u64) * COST;
+ most_outstanding.set(most_outstanding.get().max(outstanding));
+ written.push(item);
+ async { Ok(()) }
+ },
+ )
+ .await
+ .unwrap();
+ assert_eq!(written, (0..ITEMS).collect::>());
+ assert_eq!(most_outstanding.get(), BUDGET);
+ }
+
+ #[tokio::test]
+ async fn pipeline_keeps_no_more_than_its_cap_in_flight() {
+ const ITEMS: usize = 20;
+ const CAP: usize = 3;
+ let in_flight = std::cell::Cell::new(0);
+ let most_in_flight = std::cell::Cell::new(0);
+ ordered_pipeline(
+ 0..ITEMS,
+ |_| 1,
+ u64::MAX,
+ &|| CAP,
+ |item| {
+ let (in_flight, most_in_flight) = (&in_flight, &most_in_flight);
+ async move {
+ in_flight.set(in_flight.get() + 1);
+ most_in_flight.set(most_in_flight.get().max(in_flight.get()));
+ tokio::task::yield_now().await;
+ in_flight.set(in_flight.get() - 1);
+ Ok::<_, String>(item)
+ }
+ },
+ |_, _| async { Ok(()) },
+ )
+ .await
+ .unwrap();
+ assert_eq!(most_in_flight.get(), CAP);
+ }
+
+ #[tokio::test]
+ async fn pipeline_keeps_fetching_while_a_write_is_pending() {
+ // One fetch at a time: the first write only finishes once the last
+ // item has been fetched, so fetching must continue behind it.
+ let (fetched_last, unblock) = tokio::sync::oneshot::channel();
+ let fetched_last = std::cell::RefCell::new(Some(fetched_last));
+ let unblock = std::cell::RefCell::new(Some(unblock));
+ let mut written = Vec::new();
+ let pipeline = ordered_pipeline(
+ 0..4,
+ |_| 1,
+ u64::MAX,
+ &|| 1,
+ |item| {
+ if item == 3 {
+ let _ = fetched_last.borrow_mut().take().unwrap().send(());
+ }
+ async move { Ok::<_, String>(item) }
+ },
+ |item, _| {
+ let unblock = (item == 0).then(|| unblock.borrow_mut().take().unwrap());
+ written.push(item);
+ async move {
+ if let Some(unblock) = unblock {
+ unblock.await.unwrap();
+ }
+ Ok(())
+ }
+ },
+ );
+ tokio::time::timeout(STALL_TIMEOUT, pipeline)
+ .await
+ .expect("fetching stalled behind a pending write")
+ .unwrap();
+ assert_eq!(written, vec![0, 1, 2, 3]);
+ }
+
+ #[tokio::test]
+ async fn a_slow_item_does_not_hold_back_fetches_behind_it() {
+ // The first item stays in flight (as during a retry wait) until the
+ // third has been fetched.
+ let (fetched_third, released) = tokio::sync::oneshot::channel();
+ let fetched_third = std::cell::RefCell::new(Some(fetched_third));
+ let released = std::cell::RefCell::new(Some(released));
+ let completed = std::cell::RefCell::new(Vec::new());
+ let pipeline = ordered_pipeline(
+ 0..3,
+ |_| 1,
+ 3,
+ &|| 3,
+ |item| {
+ let released = (item == 0).then(|| released.borrow_mut().take().unwrap());
+ let fetched_third = (item == 2).then(|| fetched_third.borrow_mut().take().unwrap());
+ let completed = &completed;
+ async move {
+ if let Some(released) = released {
+ released.await.unwrap();
+ }
+ completed.borrow_mut().push(item);
+ if let Some(fetched_third) = fetched_third {
+ let _ = fetched_third.send(());
+ }
+ Ok::<_, String>(item)
+ }
+ },
+ |_, _| async { Ok(()) },
+ );
+ tokio::time::timeout(STALL_TIMEOUT, pipeline)
+ .await
+ .expect("a slow item held back the items behind it")
+ .unwrap();
+ assert_eq!(*completed.borrow(), vec![1, 2, 0]);
+ }
+
+ #[tokio::test]
+ async fn pipeline_admits_an_oversized_item_and_stops_at_the_first_error() {
+ let mut written = Vec::new();
+ ordered_pipeline(
+ 0..2,
+ |_| 100,
+ 10,
+ &|| 4,
+ |item| async move { Ok::<_, String>(item) },
+ |item, _| {
+ written.push(item);
+ async { Ok(()) }
+ },
+ )
+ .await
+ .unwrap();
+ assert_eq!(written, vec![0, 1]);
+
+ let error = ordered_pipeline(
+ 0..4,
+ |_| 1,
+ 4,
+ &|| 4,
+ |item| async move {
+ if item == 2 {
+ Err(format!("fetch {item}"))
+ } else {
+ Ok(item)
+ }
+ },
+ |_, _| async { Ok(()) },
+ )
+ .await
+ .unwrap_err();
+ assert_eq!(error, "fetch 2");
+ let error = ordered_pipeline(
+ 0..4,
+ |_| 1,
+ 4,
+ &|| 4,
+ |item| async move { Ok::<_, String>(item) },
+ |item, _| async move {
+ if item == 1 {
+ Err(format!("write {item}"))
+ } else {
+ Ok(())
+ }
+ },
+ )
+ .await
+ .unwrap_err();
+ assert_eq!(error, "write 1");
}
}
diff --git a/ant-core/src/client_engine/read_ahead.rs b/ant-core/src/client_engine/read_ahead.rs
index 99e3054b..7f9631f6 100644
--- a/ant-core/src/client_engine/read_ahead.rs
+++ b/ant-core/src/client_engine/read_ahead.rs
@@ -1,21 +1,24 @@
//! Read-ahead planning for random-access file readers. Transport-neutral: the
//! adapter fetches the records a plan names and releases the ones it marks.
//! DataMap sizes are untrusted, so plans bound records, never declared bytes.
-use super::files::RecordLayout;
+use self_encryption::DataMapIndex;
#[cfg(test)]
use self_encryption::{ChunkInfo, DataMap};
use std::ops::Range;
#[cfg(test)]
use xor_name::XorName;
-impl RecordLayout {
- /// The read-ahead window: records from the one holding `start` that overlap
- /// `length` plaintext bytes, at most `max_records`. Undersized records
- /// shorten the window rather than lengthen it.
- pub(crate) fn window(&self, start: usize, length: usize, max_records: usize) -> Range {
- let records = self.overlapping(start, length);
- records.start..records.end.min(records.start.saturating_add(max_records))
- }
+/// The read-ahead window of `index`: records from the one holding `start` that
+/// overlap `length` plaintext bytes, at most `max_records`. Undersized records
+/// shorten the window rather than lengthen it.
+pub(crate) fn read_ahead_window(
+ index: &DataMapIndex,
+ start: u64,
+ length: usize,
+ max_records: usize,
+) -> Range {
+ let records = index.chunks_overlapping(start..start.saturating_add(length as u64));
+ records.start..records.end.min(records.start.saturating_add(max_records))
}
/// Held records to release so that at most `budget` stay held, never one that is
@@ -44,7 +47,7 @@ pub(crate) fn releasable(
mod tests {
use super::*;
- fn layout(sizes: &[usize]) -> RecordLayout {
+ fn layout(sizes: &[usize]) -> DataMapIndex {
let infos = sizes
.iter()
.enumerate()
@@ -55,16 +58,19 @@ mod tests {
src_size,
})
.collect();
- RecordLayout::new(&DataMap::new(infos)).unwrap()
+ DataMapIndex::new(&DataMap::new(infos)).unwrap()
}
#[test]
fn undersized_records_shorten_the_window_instead_of_lengthening_it() {
- let layout = layout(&[10; 40]);
+ let small = layout(&[10; 40]);
// Every record overlaps the window's bytes; only the record cap is taken.
- assert_eq!(layout.window(0, 1_000, 10), 0..10);
- assert_eq!(layout.window(15, 25, 10), 1..4);
- assert_eq!(layout.window(400, 10, 10), 40..40);
+ assert_eq!(read_ahead_window(&small, 0, 1_000, 10), 0..10);
+ assert_eq!(read_ahead_window(&small, 15, 25, 10), 1..4);
+ assert!(read_ahead_window(&small, 400, 10, 10).is_empty());
+ // Positions past 4 GiB address records exactly on every platform.
+ let large = layout(&[1 << 30; 6]);
+ assert_eq!(read_ahead_window(&large, (1 << 32) + 1, 1, 10), 4..5);
}
#[test]
diff --git a/ant-core/src/data/client/data.rs b/ant-core/src/data/client/data.rs
index f836158b..acd3a655 100644
--- a/ant-core/src/data/client/data.rs
+++ b/ant-core/src/data/client/data.rs
@@ -22,7 +22,6 @@ use bytes::Bytes;
#[cfg(feature = "native")]
use futures::stream::StreamExt;
use self_encryption::{encrypt, DataMap};
-use std::future::{ready, Future};
use std::num::NonZeroUsize;
use tracing::{debug, info};
@@ -345,7 +344,7 @@ impl Client {
/// primitive symmetric with `data_upload`.
///
/// Map resolution and network fetching are fully async and also work on a
- /// current-thread runtime. The same workflow drives browser downloads.
+ /// current-thread runtime.
///
/// # Errors
/// Returns the underlying fetch error, or an encryption error for invalid
@@ -360,45 +359,15 @@ impl Client {
&self,
data_map: &DataMap,
concurrency: usize,
- ) -> Result {
- self.data_download_with_progress(data_map, concurrency, &|_, _| {})
- .await
- }
-
- /// Internal observer for verified records; reconstruction still uses the shared engine.
- pub(crate) async fn data_download_with_progress(
- &self,
- data_map: &DataMap,
- concurrency: usize,
- progress: &impl Fn(usize, usize),
) -> Result {
if concurrency == 0 {
return Err(Error::Config(
"download concurrency must be positive".into(),
));
}
- let received = std::sync::Mutex::new(std::collections::HashSet::new());
- let total = data_map.infos().len();
- progress(0, total);
crate::client_engine::files::download(
data_map,
- &|address| {
- let received = &received;
- async move {
- let bytes = self.fetch_data_record(address).await?;
- let mut received = received.lock().unwrap_or_else(|error| error.into_inner());
- if received.insert(address) {
- let completed = data_map
- .infos()
- .iter()
- .filter(|info| received.contains(&info.dst_hash.0))
- .count();
- drop(received);
- progress(completed, total);
- }
- Ok(bytes)
- }
- },
+ &|address| self.fetch_data_record(address),
&|| self.controller().fetch.current().min(concurrency),
&crate::runtime::sleep,
retry_data_fetch,
@@ -407,8 +376,9 @@ impl Client {
.map_err(map_read_error)
}
- /// Download a plaintext byte range using the shared streaming reader.
- /// Resolves child maps first and fetches only records overlapping the range.
+ /// Download a plaintext byte range. Resolves child maps first, then fetches
+ /// only the records overlapping the range and decrypts them one chunk at a
+ /// time, with 64-bit file arithmetic on every platform.
/// Length is clamped at EOF; a start at or beyond EOF returns empty bytes.
///
/// # Errors
@@ -419,8 +389,22 @@ impl Client {
start: usize,
length: usize,
) -> Result {
- self.data_download_range_with(data_map, start, length, |_| ready(None))
+ let fetch = |address| self.fetch_data_record(address);
+ let cap = || self.controller().fetch.current();
+ let root = crate::client_engine::files::resolve(data_map, &fetch, &cap)
.await
+ .map_err(map_read_error)?;
+ crate::client_engine::files::read_range(
+ &root,
+ start as u64,
+ length,
+ &fetch,
+ &cap,
+ &crate::runtime::sleep,
+ retry_data_fetch,
+ )
+ .await
+ .map_err(map_read_error)
}
/// Resolve a shrunk (child) `DataMap` to the root map that lists the
@@ -441,40 +425,35 @@ impl Client {
.map_err(map_read_error)
}
- /// As [`Client::data_download_range`], taking records from `held` and
- /// fetching those it resolves to `None`. A record that `held` resolves to
- /// an error counts as a failed fetch attempt, which the read retries by
- /// fetching. Every record is requested at once, within the fetch cap, and
- /// held records are verified too.
- pub(crate) async fn data_download_range_with(
+ /// Read a range through a validated index reused across browser seeks,
+ /// taking records from `held` and fetching those it resolves to `None`. A
+ /// record that `held` resolves to an error counts as a failed fetch
+ /// attempt, which the read retries by fetching.
+ #[cfg(all(feature = "browser-wasm", target_arch = "wasm32"))]
+ pub(crate) async fn data_download_indexed_range(
&self,
- data_map: &DataMap,
- start: usize,
+ index: &self_encryption::DataMapIndex,
+ start: u64,
length: usize,
held: impl Fn([u8; 32]) -> H,
) -> Result
where
- H: Future>>,
+ H: std::future::Future>>,
{
- let fetch = |address| {
- let held = held(address);
- async move {
- match held.await {
- Some(result) => result,
- None => self.fetch_data_record(address).await,
- }
- }
- };
- let cap = || self.controller().fetch.current();
- let root = crate::client_engine::files::resolve(data_map, &fetch, &cap)
- .await
- .map_err(map_read_error)?;
- crate::client_engine::files::read_range(
- &root,
+ crate::client_engine::files::read_indexed_range(
+ index,
start,
length,
- &fetch,
- &cap,
+ &|address| {
+ let held = held(address);
+ async move {
+ match held.await {
+ Some(result) => result,
+ None => self.fetch_data_record(address).await,
+ }
+ }
+ },
+ &|| self.controller().fetch.current(),
&crate::runtime::sleep,
retry_data_fetch,
)
@@ -482,6 +461,57 @@ impl Client {
.map_err(map_read_error)
}
+ /// Fetch and decrypt every chunk of a file as a complete download does:
+ /// within the adaptive fetch cap and `concurrency`, missing records retried
+ /// together in deferred rounds. Each chunk goes to `deliver` as it arrives,
+ /// in any order.
+ #[cfg(all(feature = "browser-wasm", target_arch = "wasm32"))]
+ pub(crate) async fn data_download_indexed_chunks(
+ &self,
+ index: &self_encryption::DataMapIndex,
+ concurrency: usize,
+ deliver: impl Fn(usize, Bytes) -> std::result::Result<(), String>,
+ ) -> Result<()> {
+ crate::client_engine::files::read_chunks(
+ index,
+ 0..index.infos().len(),
+ &|address| self.fetch_data_record(address),
+ &|| self.controller().fetch.current().min(concurrency),
+ &crate::runtime::sleep,
+ retry_data_fetch,
+ deliver,
+ )
+ .await
+ .map_err(map_read_error)
+ }
+
+ /// Fetch and decrypt one chunk, retrying it on its own deferred schedule.
+ #[cfg(all(feature = "browser-wasm", target_arch = "wasm32"))]
+ pub(crate) async fn data_download_indexed_chunk(
+ &self,
+ index: &self_encryption::DataMapIndex,
+ chunk: usize,
+ ) -> Result {
+ let plaintext = std::cell::Cell::new(None);
+ crate::client_engine::files::read_chunks(
+ index,
+ chunk..chunk + 1,
+ &|address| self.fetch_data_record(address),
+ &|| 1,
+ &crate::runtime::sleep,
+ retry_data_fetch,
+ |_, bytes| {
+ plaintext.set(Some(bytes));
+ Ok(())
+ },
+ )
+ .await
+ .map_err(map_read_error)?;
+ Ok(plaintext
+ .take()
+ .expect("a completed pass delivers its one chunk"))
+ }
+
async fn fetch_data_record(&self, address: [u8; 32]) -> Result {
self.chunk_get_observed(&address)
.await?
diff --git a/ant-core/wasm-tests/README.md b/ant-core/wasm-tests/README.md
index 83d1b59d..e8a3d50a 100644
--- a/ant-core/wasm-tests/README.md
+++ b/ant-core/wasm-tests/README.md
@@ -63,6 +63,20 @@ on a current-thread runtime, verified records, and range boundaries. Generated
WASM additionally downloads a native shrunk DataMap through the mock network and
checks media ranges across chunk boundaries and EOF.
+`large-download.test.mjs` streams a native-encrypted 4,303,347,835-byte file
+through the real WASM decryptor and checks its complete BLAKE3 without retaining
+the plaintext. It also covers public/private seeks across 4 GiB, actual disk
+writes, fetching bounded behind a blocked write, `AbortSignal` cancellation of
+`pipeTo` and complete downloads (including during retry waits, a stalled
+destination write and the destination's close), invalid `pipeTo` calls that
+leave the destination untouched, writer errors, JS allocation and output
+failures, memory budgets, progress and invalid offsets. The compressed fixture
+is about 250 KiB;
+regenerate it from the repository root with
+`cargo run -p ant-core --release --example generate-browser-large-file`.
+Generation processes the entire plaintext using bounded buffers. The full-stream
+test normally takes around twenty seconds locally; it has a three-minute timeout.
+
Upload discovery regressions verify native's twenty-to-seven fallback, reject
persistent five-peer results without payment or PUT, and ensure the browser
adapter does not bypass genuine failed-connection suppression on fallback.
diff --git a/ant-core/wasm-tests/download.test.mjs b/ant-core/wasm-tests/download.test.mjs
index 42cfa57b..ad492784 100644
--- a/ant-core/wasm-tests/download.test.mjs
+++ b/ant-core/wasm-tests/download.test.mjs
@@ -368,7 +368,7 @@ test("a read in progress keeps its records when another read needs room", async
} finally { reader?.close(); client.close(); }
});
-test("a DataMap whose records range reads reject still opens", async () => {
+test("a DataMap whose records range reads reject fails to open", async () => {
const records = [0, 1, 2].map(index => {
const content = Uint8Array.from({ length: 1024 }, (_, byte) => (byte + index) & 0xff);
return { address: contentAddress(content), content };
@@ -380,12 +380,11 @@ test("a DataMap whose records range reads reject still opens", async () => {
const rtc = mockWebRtc([{}]);
for (const record of [...records, map]) rtc.stores[0].set(record.address, record.content);
const client = new BrowserNetworkClient(rtc.endpoints);
- let reader;
try {
- reader = await client.openPublicFile(map.address, undefined, { streaming: true });
- assert.equal(reader.size, 3 * 1024);
- await assert.rejects(reader.readRange(0, 10), /contiguous/);
- } finally { reader?.close(); client.close(); }
+ // The reader's index is validated when it opens, before any read-ahead.
+ await assert.rejects(client.openPublicFile(map.address, undefined, { streaming: true }), /contiguous/);
+ assert.equal(rtc.requests.filter(r => r.method === "get_chunk").length, 1, "only the DataMap was fetched");
+ } finally { client.close(); }
});
test("read-ahead retries a failed record only after another read", async () => {
diff --git a/ant-core/wasm-tests/fixtures/large-file.json b/ant-core/wasm-tests/fixtures/large-file.json
new file mode 100644
index 00000000..7b2e3ec7
--- /dev/null
+++ b/ant-core/wasm-tests/fixtures/large-file.json
@@ -0,0 +1,4136 @@
+{
+ "address": "bdf831b9fd46588ecd85bd7563732d44430ccf6fce27e81514a00057881bca37",
+ "byte": 90,
+ "hash": "1b382a68936c50a2be8f4caa7f579c90cf649544a46f07ce5adeeffc20f5a3cd",
+ "records": [
+ {
+ "address": "00a383fd8e74834056468a713393d8ba510e7e1358f32d22ac36e04516f05559",
+ "content": "6f08f9643d040a9c37ecdc0eb28a03bf2eb20f398e107075a018627e8b29"
+ },
+ {
+ "address": "00a6757a7a690c27618435c78ff53cdc8e6f3158ed51afacaebeb4e09cf3b668",
+ "content": "b075fcdfba1f1d59c3061bc2feaab9d9ff5de335b74801aeb59623b98244"
+ },
+ {
+ "address": "00b350b0c69634ecaa5ed566ffa3985e05a5033c66fb168dbc6172fee756e7f8",
+ "content": "65e1689cc91334ff11ed34a50492d6c408e13af7a0a5a3647366a12955af"
+ },
+ {
+ "address": "00b85634772d274ad5f54104c3ec396c5ea430b4586b94d11c2db81d8f28365e",
+ "content": "fbc4ed645214ee44d1ec6875e9a8762611e6cb06d769f32116eac3598fc7"
+ },
+ {
+ "address": "00d0a8130f3cc2c7016b0498133e3d364ec6784824184d0bac5d7cc1d5f01e2d",
+ "content": "8c7c208884ad0ef46aae1c59297f69f517c66e62401048c0572763bfe0fd"
+ },
+ {
+ "address": "0185ad7f4cbb923745156e50709bce92e1db3a6d2f1d669478272f7be6514236",
+ "content": "56fed66a14fc916dff4e125c4f960e041b8436cfea704d885af9c645fb6c"
+ },
+ {
+ "address": "024eef75532cf9e30c65ac641cdedafa2725f9052dae048cf526529f3d83383e",
+ "content": "ba7532472d86d484a13caf0b4c7c9881bde4e3d4dc80ed3814930fccf02e"
+ },
+ {
+ "address": "027371aa5878c730b4e1642d799e20035ed2fdf820f4dd2a7cc0f573669223a6",
+ "content": "70dca9da9af2ff79d1ff3f992566e5b1930eb7a22e5b3c5c220d4a739d5e"
+ },
+ {
+ "address": "02966b29d75f594c8c080e50d66832daf2f90cd187e59f5169166aeabd1b8c11",
+ "content": "5e7c065404e22cd101543ab5fea5eee2a48cfaaae23bb9d167e23d7b5d60"
+ },
+ {
+ "address": "02bf99736e332c4fa0636f2242fd165e50abea6cc6bbec23af55413b3f3fdb54",
+ "content": "a89db21c6199670098502845235ddd00bbcdf25103cbcf91a9377438f550"
+ },
+ {
+ "address": "038f75dd950d2982316f2084b90c5d9ba2ed6acb315aad0f17c8cddb45d37872",
+ "content": "1d8242bd3ecb786b5e50816ae78aedcf81c46c86657bf0b0f1a590b3dc4e"
+ },
+ {
+ "address": "03bb546174362bb181435ed2ad82b9a7621b48fc53182ec2620ab16499f9461a",
+ "content": "4c0b4b7b97cd75abae0a8d8345b155bfdc050f9d7d8a04a4a7468d8eb9e5"
+ },
+ {
+ "address": "03e653d780f5d26640f447cc3e7c2fe4291afc6db770fc4e5c686c2527daa0b6",
+ "content": "af0947156425988c6b1184be139a5e24945572d87de806097d63d599d7d1"
+ },
+ {
+ "address": "043856ba53a21dad8b1870191e46c1fd44dd536796e37881b62007462c71f0c2",
+ "content": "347374bbcb1d82b8e1e02c417e5e34fabb5134ad395dedf99722208e116a"
+ },
+ {
+ "address": "0442dfea398cb6c146cd3143427b72ff56046d7eebd97ba87487a6368216b08f",
+ "content": "9bdb6c24b8597d40a1629a5516cd56ece818bdeaa6ef6cb284b3e2b4159c"
+ },
+ {
+ "address": "0504d0599cbe0aeda53fe3ff7f3413781c07dd2126d73ee37eefce69b33a84d2",
+ "content": "e9d6e8a1e82f2eec1bd7a7199a5a9c574941fba2da74ab6f248e5fcd0681"
+ },
+ {
+ "address": "0520772c010c59d44d56239b04ef9a2cf8ff5510628952e50272605cf4bf98fd",
+ "content": "fea0ed7bf997f5f795d7d72c60263c9079e35d7b33bf5167981b53e7797d"
+ },
+ {
+ "address": "059613880f9acd711e100ed2f47e5eea554b1599f862d801af2520ed3f1b997e",
+ "content": "4a68cb1d79fe3ed4e0e65feff516fed2b242bd12bbda4f8757ec6e45dbbd"
+ },
+ {
+ "address": "05af77ff1e190ecfc6b5c003db6789a04c2a0f30e1548e55402279543c200178",
+ "content": "f7aa8ea7f46e72624af585fefd3f404f1f8534ad80058b5e8b1b5f5fca92"
+ },
+ {
+ "address": "05bb3cc68f44ce2867531c5a8765d71a960ea1a396c5288405863e2919b6df5d",
+ "content": "466648c098b57f8ade691d0a63778f3bc30b52253eff31c73f0bab259b6e"
+ },
+ {
+ "address": "05d6ad308a100b15d60931a2edd28aa12b0a8c1e6d98573048fa945c141ea0d0",
+ "content": "cf7246adeda6f14fe21e00d87fda57fceac121a2aa821b41a78b49996f48"
+ },
+ {
+ "address": "06173d4c8d1a0c6f47a79c1ea042f5565fc7a2c27ec393e5044bdff7766e8814",
+ "content": "1f8cfbbd6c17e4dd3b9131556fe4085486d0dc5f9245d5d53a8354b3f763"
+ },
+ {
+ "address": "067db82d18ebb056e2adb10c28ed19b1a5e2fc71e284e9e2256ffda1e900cd84",
+ "content": "fad4694ba439a012bc9d8d8a6e29e0e00c9dbf537195ec0169b82e1df8e3"
+ },
+ {
+ "address": "075cb374444f59534a8e7e086847c18adc3e21ccbe3de04fb69a0580faf0dfde",
+ "content": "f41d6a7c383004122a122417fafbcb232915bd0a2a1ee14be197e7d1c7d0"
+ },
+ {
+ "address": "075d16cf43dcb725725de578c6b1037e5cd0f8b8a6cc8cf85a0387c34c19b2dd",
+ "content": "1271e121e68c30dbeca4ea04c5b613d4e1b597a18637911aa9c345f1be15"
+ },
+ {
+ "address": "07e801ff714ad2edcca3c516b7229bde586a55e714c6be717bf97d020a10e779",
+ "content": "60781e4b7f17760e86b2ef5003e5126ad3f2d39aed2ce734fd87f8aa4427"
+ },
+ {
+ "address": "0865eea4183a5d2b7b9cd1c3f402532de0e9d053f0173c952ebf1032bf37d9b5",
+ "content": "ac3cb1644183c83dd579674e32bc10ea4def47503dae24bd0bbc6b2b829b"
+ },
+ {
+ "address": "08da97e61b5d5701bc580db22f76ab479f5906f4139a362df08c35e96977186e",
+ "content": "c83ecc6a378f406c795f0c698d15be2ce2992f57399f48dec2c73412a14b"
+ },
+ {
+ "address": "08ed166301f6b29d60cd94c5643c2862ef4c7170013302677f78eedd50287f24",
+ "content": "e922f1cb9983b856bbbe2628ef918cdd627c40dbb4a2a727b3d7765aff0a"
+ },
+ {
+ "address": "09429a5186540a73173d486768608ae11399aefe53557e34ac091bc71b47ed4c",
+ "content": "940e0ac3dbef780cdeff79263a3f0009351093fd5afbc76548d18b61657c"
+ },
+ {
+ "address": "0997b86567b3e26361cc57c07360faf53f2ca0e300284dfd19efd9fc03247df3",
+ "content": "5350a2b1633e603c1bed8d5b33978cece69c047966b41c1bdc79fe038a10"
+ },
+ {
+ "address": "09e534af79a6a1ac38df494a450374d4b88c4826dae4d36fd3bb65e5ef8e83d0",
+ "content": "eff873b2f5284c9071167abdc26545a6714d8f3177225886b40393c227ce"
+ },
+ {
+ "address": "09faadd6ce02a3387d0ab7e0d46a1745a6775e96da940ee9d7263e3900723d0b",
+ "content": "55a342f85382a4f37afd6383d930b46be5797a3aae942324875b909ea587"
+ },
+ {
+ "address": "0a2ffd842c33377f6c688dee2326908cbcad52876100abc80a766059bd35b149",
+ "content": "cb0fa7b7de12817ca478d8092b5a3a7cc43a416a66c5d1f68e8f46ff6fa5"
+ },
+ {
+ "address": "0a756a5f9d028ff94d4dfc44658b38cc157c85caee77e3a3c2dbb2e570a1acf3",
+ "content": "e81f35410c7dd10c6d1986b7731c9dfa618ceedf08eccaa4ba1c20f60002"
+ },
+ {
+ "address": "0a775971b96e79fae3cdd306e45e885e32b3a8f29dc041f884bf9bf366651667",
+ "content": "b6666f7ee9ea620a5837d99b342894c96ba674a9ad104f7b1601eb4b4e66"
+ },
+ {
+ "address": "0a84345252c34819dd77b5b13da1444d63ea9d518ba3d7831ed09abd77d463da",
+ "content": "d1d3ab6cbfcf467cdf3ec76d237c1cd7b5e3fc8b5b55c0317a54a540c1d3"
+ },
+ {
+ "address": "0a911580c2c508d71dd2869ebc47d5fbd8943db4d454589c37e9bbee5a8d8a48",
+ "content": "1ed97debc21628319ca85c12bbbd557d2e21b5ec120abb000d5c69457372"
+ },
+ {
+ "address": "0a9a160214716b1a0b1760cb0d2253cc28ed9e0a382e801ee4fc856b009da6e4",
+ "content": "adf6b18c09eea5452d84ce05a29780e5a5c94bb33ffe567a90428dd220f3"
+ },
+ {
+ "address": "0b82d8a38d5d6a937ad05a29db0c2804ea592ad98678950ad703c0fb1b2fbefe",
+ "content": "880094f83be437f9d632b266298779002dff5206884e666f7b824ed6927b"
+ },
+ {
+ "address": "0bac26271dff9db4df0c906519b7efefea79650fc3a96f817d73ab2eaea99ed8",
+ "content": "a47c2f6856a2eb617501cbab645d6a3ffd1a2c5680869872974ac8c69002"
+ },
+ {
+ "address": "0bc5b2b4d889b9ba6977c2bfe0de9241141dfae5da8c4b96ef5fbafdb35d1e46",
+ "content": "5831bf765a234e46292f2813bdb1e9d48c2e748f4ff1b252b87ed3ffbd17"
+ },
+ {
+ "address": "0bf1861f7daa8c755fa8d87cfdec818d1dd5a4687a2fc91cded6a8c9eb3e03e8",
+ "content": "f892b5c7c6e6f1f478ac644040c75f0bc4fd95942881264a018895eedb0e"
+ },
+ {
+ "address": "0c2ea632527a412f559fa6bf2d53937d6bb79cf6e5f12d7d1e37054acad950b0",
+ "content": "916e08195566e700a1c2f58a41e79c355639dd71167873575058b3d16ca5"
+ },
+ {
+ "address": "0c8be0f2f4372b464749ffaff191f4183e918d4809cce4bb0730813086b9c752",
+ "content": "25d6693a2294ea50f79d0b0daf6ff096c604c6936e05dbf9cd4dfd00b1e1"
+ },
+ {
+ "address": "0cfde5ee7e3cf6fd22e59f8bfd9f533bc9dccdee4c747cedea496e9d65eb102c",
+ "content": "0aa3126e819cecc361cfc5f7cdad77e8b8e96a5495cfcf6c1973340750ee"
+ },
+ {
+ "address": "0d034274681954f4a766b7df0406ded5d180beb130fe0036006a07b73ef8740a",
+ "content": "4d0c16de5a879e08a1c5d795a5b24b047a0e7f3a895665fbc7864632d20c"
+ },
+ {
+ "address": "0d4fa403d279dd0f9c73d41b5e66143c522999cf3191dff2e5bafabcb363943f",
+ "content": "667f024f8c767af81b738a6f6d3978b39ede8d94ecbaab5afee80a31cfbe"
+ },
+ {
+ "address": "0d6c30227b81b056393adea92c84555e3a36c7f0f3319bd21b13618186d412aa",
+ "content": "ab26a6bc752a4c747ae4ce013723158bb0e07569825bbdd4185aa4bb06df"
+ },
+ {
+ "address": "0d724bc44a9563ee3ecb1946ceef2efd3defc7b2f6d18829c1417f5c63c9362a",
+ "content": "72fa400bf00ae3d55b7d085fff3c78b4335ecf1514e92065e1bb4af124f7"
+ },
+ {
+ "address": "0d8c639b9591610b83900ab870825aefbb9a56f901a7dbfadf5d030a7ad3bdfb",
+ "content": "07fca1f9484aab049ba43fd62f22de12455f4676fa2c0ba4dadd568d5d91"
+ },
+ {
+ "address": "0d9ddd9b0d3afad517a2d02a832275cf9de27ec351f916cd3b6373ff1dd80864",
+ "content": "4b36b0621d210dc6b54b11c432bfa1a526cc88ab80624cd80e97a5596a50"
+ },
+ {
+ "address": "0da4b272b1615908a41f909a2f3000de5dbecbc450138c87ae3b80d16d49efe8",
+ "content": "4668f1d62e849131d1013234b670876fc253e681274d45ddcdd96018793d"
+ },
+ {
+ "address": "0e66172de8284644cdc71fe3fa1985dd18948ecf357f9cae2e2d49c46d1955cf",
+ "content": "35b7d0f198d95654f607ac885f24517021e2574a1846e0e4416daf16aaa7"
+ },
+ {
+ "address": "0e741414f7565a716deb158eeb880c30964e97077802617a5c0a2022d863bae3",
+ "content": "5fc22d8a8f44d4b9affe39bab1275c01410eeab4c958777775cb136fd53d"
+ },
+ {
+ "address": "0f69d11c23913ed1487ce6e012c58adeb69285b85cc1722b7f00b8c896fb41ad",
+ "content": "f256f3a7f1f786954fa58693a7478cc5ca454426ab50d3a31315d0c21497"
+ },
+ {
+ "address": "0f7568fd961b57e366c7c7a39b7bf36bc70d7f0816feef62275bf57aebcb452a",
+ "content": "6a6a9319a1c00d807ab219725475bafcc6397825e95645fd903e83e427de"
+ },
+ {
+ "address": "0fd82b992460ed1ab42ddd42e03261e67c7c6a707123ffaee317e45a764199e2",
+ "content": "10da69e34aa22c544efd7abe839384666855e631b16ec0e07fdfdd1fcf5a"
+ },
+ {
+ "address": "0fddfdd0870838a1e6bb743d67a972c750fbd3baa30341dd642f7c049cfd74b9",
+ "content": "e1e87b2fc8accf6ee93036c3db61319dd1c25ccd4cc4892afb988fa2369b"
+ },
+ {
+ "address": "103ed67937cc8458c9ded709575d32bf506794239e647966e190f3bf46176d21",
+ "content": "b36809940b41ca58a1239c0c80a2829ccb01e2f04e99665efffb94c91573"
+ },
+ {
+ "address": "1057a79935ead5f382c7b5ddd9a9725f3b8dadb429e22653afc8de92408834d2",
+ "content": "1d405e6806a7408aaba82471d706a5fd68be69b6b9123452990b2d41b3a3"
+ },
+ {
+ "address": "1057c657bf167b159209b439b3cdb90ffcf62fbfe73d9e6f52a980beec8a5e8b",
+ "content": "39da4f3b0d5856cee7c7c085c74d5c5627838b11576314893173cdadb00f"
+ },
+ {
+ "address": "1086218f84f9fb77e64cbed58a96ad4ec0029ff69827ef95c7e7f738886339aa",
+ "content": "43155e13c9aab4c45d10bfdcf4e09f4db04cbec3c8ed8490a9e783a224d8"
+ },
+ {
+ "address": "108b4af7d3ce1dcbfbeeed302e2704703a76e0d4fa460aee1f46413870f6fbdb",
+ "content": "94b863457d0d7faf26a669580769c42d3f7192a077aa4b85aa79c4806c8b"
+ },
+ {
+ "address": "10a1beae05efe5ff6180ad06da193f8bc9f07869e5454fcae067a2bf93c8f88c",
+ "content": "a83aa68885651f7857cd604530cfca7a44f21638ab4185976575509d9d37"
+ },
+ {
+ "address": "10aacc51bef961d240cfba948e17e2892e3c350ab5a4a2397ad2dcedad362648",
+ "content": "be13aab4df4e8a6569a68581c036df58400959d06f4a86447b01c37db760"
+ },
+ {
+ "address": "10b6701939074e8c35d1e27bc09903c6eeef6a76a5f12497ec78cb385ef71c55",
+ "content": "59e0e21f9c554a435c5ae00e8e17bdc6c033d32ba7016ced4ed00ac45e03"
+ },
+ {
+ "address": "1132a93d32d7d8248eff09a6c5f04da79d3b584289aedc3934dba08a3d9aba42",
+ "content": "01fe4518f76ba25d5d25117559d14008c0720312d3050eafd8e47c4aec37"
+ },
+ {
+ "address": "1181683ccfabc946403d41afef7927f7fd2ddf40d5e2c2b115d755d9b74f445a",
+ "content": "bc0571351beeeed9de914988bf285e1e6a9c69af55913ad3f3fcc7361644"
+ },
+ {
+ "address": "124bf0dea99008557d5ef13eb59b90b04f3a8e6100d8c70288feb6d79021fe18",
+ "content": "96bc645821e9312474d2bf04958214d55a1266e694f6d76269e5bc19d6fc"
+ },
+ {
+ "address": "125af79c6304841447220f6a14025bb73cf6f664f4b8a6019f7f08ad09054114",
+ "content": "166c414ded7284b948abd111a3a2a93a313e521b748525345070497d30aa"
+ },
+ {
+ "address": "12698598d9ffd0228351ec3a6bfcbcfc965089b666be9e4a1636470eac3be8a4",
+ "content": "abbab03a47f5391213209a550bd43a8a0912375f103a0413d503f72f0f87"
+ },
+ {
+ "address": "126ff5a61154b70f08e5ad286f92371ff982041f7f4e6f6e896ee1c39e3e9b3a",
+ "content": "b54880580819b38990cab8f5128df1fbc79de4cf0e6998fd9f321929afd9"
+ },
+ {
+ "address": "12e8ecb3edacc99b36a6ea2104a116eef0c227ebe48962e0d860e1fbe7f127fd",
+ "content": "7ef19c05efc3935d95e66a9db1a4d4dd5139ed1a859d7a86934418e7510b"
+ },
+ {
+ "address": "13527eda870261d3fc48f2366bc7acbe5060280d752e3241f0c774925e270b2e",
+ "content": "57217f83d101c6de88d512f04f2383b94cd3b9ac5a9743a9bce498f62bf7"
+ },
+ {
+ "address": "13db866e71e3b6e57fa7d163a65e9c1444989104c6425d9f43a8d024b5dc7a9b",
+ "content": "fc5f9dbe51446e5530fef2f56324e9b2c067b729cc17066dca1089aabaaa"
+ },
+ {
+ "address": "13df5edc9dbe6f04109b0ad523480335c3e99dc9b0edfdf25c377fefe821713b",
+ "content": "2b9a3e08f6b6028be0df36645ad0327fb15e0d08ed0a53458b88527cc18d"
+ },
+ {
+ "address": "13fb377b2889f70c1a44ce4551837336bcd64791993fa9b17c074cb42eaecbba",
+ "content": "96f741df4251957c89d225831566e1b2334cab6bdcb8214b601882fd25b4"
+ },
+ {
+ "address": "1419024838d9289690bf772280edfb9f30e95bb2d1f01f8070165c0415b5cbad",
+ "content": "ae000d9c092b32aa842eb1696a15004f41d899e1998a8988bbdf9300d728"
+ },
+ {
+ "address": "149e17e4b963a256e5e4ac99e6924f3b192bbe76fecaf912bd839ae1baa08845",
+ "content": "9a38b58d2da07de6af9a15f6fd58aa9b66d930fa8cc18ee9bf4623d53e76"
+ },
+ {
+ "address": "149ed4c89470b2ad0e3d81f81637a582f0c16c09a17f03b926495421a7331228",
+ "content": "cc5530e99ec749032a072287034b125d2eba761277e4dd927a6d05fa28ad"
+ },
+ {
+ "address": "14d5d72b82ee5740b85a701f632cead987af48ae45cef6c2e7b87c06bcb99e27",
+ "content": "d89cafe03c98b61944cd9bec1cbe4746946709e5db2a1af5814447dc2014"
+ },
+ {
+ "address": "14ed7958466058b156715464b247d8edc111192277add19330ffd9883e326942",
+ "content": "d431e0710a1dd7b0f435fef792620c48aa77c96b214b96da32203e703431"
+ },
+ {
+ "address": "1610c616fdd414a9bd917de88f2fce1c42d31a605ea0426f5c80effbf844a35f",
+ "content": "7153df0237d64ccfd9bd6d7e48a45925d3778ea67d80e1e3795fd78acb82"
+ },
+ {
+ "address": "1675ab35f3c49f26d8b9066e9d10a725fdf187d1760b98332be11e8d9cd6b63e",
+ "content": "8d2b4c7c3fa9d9b6cdb3c42451a6f33a5c7b4d0b0e49ca40dfeae1eeaa5e"
+ },
+ {
+ "address": "168900f34c5eb0c7682569f0c5827e230e3c3526d01eddfcea7699f3e86867b0",
+ "content": "5c5eef3e89f0768dcd922ac05beaf47c389d905722bd758c86ac6f97a5c3"
+ },
+ {
+ "address": "168ec3bb45bf942119073d1c8f012bba623aebb521b4e551f96bc0fdad1da555",
+ "content": "3563d9066caa8ce6e2cf0bd196de6be9241dff9289710902b7cf793fa70b"
+ },
+ {
+ "address": "16b3e6ed77b36b412f7db6c0251fb4ae955dfea8a6474e80348e751af13deb17",
+ "content": "3befcf0dec78ff4acd741fdaea6144ad40bb6df9535b1135b06be3188a26"
+ },
+ {
+ "address": "16d1f60f07c02cfe47ba24c0e1a6e99f0fc9059d1f4d7dea56534cfd506882b5",
+ "content": "ee1139146d7582ba418f57b2ce67a26a32e9f52924bcd6cfb066a5e99a5f"
+ },
+ {
+ "address": "174242d639631c680c3688a17ae459b933efd28f76e4dc6cceb028930c274002",
+ "content": "5ccc5ef87eea685ced9fd13a6c5f5e2c952a9b19067107bb6e9a3e090ef2"
+ },
+ {
+ "address": "1752ccc22b5aa237c2452e901ef56285ffb712dc1cdaa1c18e0d54ac3271dc4d",
+ "content": "f1dd1fae11fe0ccc0825529f28bc671f3980450bd07d97ea2b3b20e9dade"
+ },
+ {
+ "address": "1792fd3ffda2d6f8e6cd595c379a6571fbcc4751badf5025c4f57420059bbaf1",
+ "content": "bcd76f85a3d8848b2e3ff4cd7d79935e1d95099067f71703ff7900f29949"
+ },
+ {
+ "address": "179b41556a0528043a6793ca66ccd20af52ad72a83bc244fe4855820bc3a52df",
+ "content": "267506cba3a494339c3d2e7f53501f5a6294f4c02d94feea254ac57ac64a"
+ },
+ {
+ "address": "17bbd5e28967e6309414ecc140f9702d40c28500f5b011318f98927df18a5345",
+ "content": "d749d195f0529f3567abc50e5e45e93d3fe840d39fae49350e2fed112f04"
+ },
+ {
+ "address": "18ef8f6bcc1eba8f739314e85db371fab2054640234872ff1e7b700f2dd4c699",
+ "content": "3e6432c1b53d0d0fde4c9f46407be21703a1d75e6894a512a0841bab6865"
+ },
+ {
+ "address": "191f9592a921482af7fed95efbf41cf4cdb3f14828c41317580e129b0cc0e90a",
+ "content": "6d728e1f6dca205fbd98200460805b1e3409f455f3419f18a8ee46f6dcd5"
+ },
+ {
+ "address": "199511d7863c8113e257fe938163fa2d2fc1d482c086bdaa2d6527d6ff48733d",
+ "content": "83af4ffdaef1ed5d13e672f7963282ea0e946b2834dac8ba1437a698f3a6"
+ },
+ {
+ "address": "19a19d88590159b77fb83de386a6da071117bf3937dd88e07f74809f146a56c7",
+ "content": "11550cdf0500ddc4ed53db71c8e16adf4758858048e234e616cd6c035e02"
+ },
+ {
+ "address": "1a6d3ddd08a1c589ffaaca966cfbcd3237f8b1c820467067460e21fd1d0fd29d",
+ "content": "dff79501d39589513b238145c4eeca819f95b8444ba9bb0120c44813b932"
+ },
+ {
+ "address": "1a816d5ec4f545f5ec4605f81642ca7c142677ee53046f5dac1eed4fb276939d",
+ "content": "fbaa3b545507c9e3eac63e64b9fd399f01d3b85db476c50ee70bf03f5a6b"
+ },
+ {
+ "address": "1aad2bdb155aa891b74b56e7dd7575d15ff672d79e8f7a841b20d142d327db38",
+ "content": "4b585ccec438dd365d20a6c86781989f84960b6afb77328090ccf72afb9e"
+ },
+ {
+ "address": "1ab473a07f621add4eb6fca0180ddc785d95317b7c354c2f52baaa56157436e1",
+ "content": "f21f35f606a49b4eb3e83ce73d8bde14ab104e84c4d756dab53e330492c5"
+ },
+ {
+ "address": "1ae897cea702f9660254250efbe81904c954ea5981549036e56c89e7a369227c",
+ "content": "44920f918aa354bd6fb155169e37eb8db641e3ae19f48cf9da770aedf5b5"
+ },
+ {
+ "address": "1b051fe762a69a898bb58b653cabf1e73176eca2da8d781973e06026d2c7caa4",
+ "content": "a3271d2290b04ca8c48b585f94811b8e18822b2ebd0099c1e0e22f20e1a7"
+ },
+ {
+ "address": "1b271c1a83ee29748f7939318674d840a3a5477f047b0bd780d17670f50498a1",
+ "content": "9b3f8b7f3da3c07ba0b8ba0d52fdbee523be99842293d64d7ed46a88d321"
+ },
+ {
+ "address": "1b3c66bbb925a99463580bc5541fa0c7824b24af9758b59e950f18c199ba3bc8",
+ "content": "aa662559bf6b9b41d1cb4adbc9782a4a091c392088661e304cc0681d32fa"
+ },
+ {
+ "address": "1b778a10f9b7bb552bcb177e80e8d233a9918d691510732cdeed74b2138d35d6",
+ "content": "163191bee96d982232650240679e1753852e564a13dbebe056ff4066022d"
+ },
+ {
+ "address": "1b9a22ac679c00752aa84b7156febd5c1bde35bf97aa0607da7e2714692c26f6",
+ "content": "87553acd4734ca571d3716ecb554b9b8d71c6ea14997ac84e5406d83c328"
+ },
+ {
+ "address": "1bf997280c8634acd51d40ab8f7612b4582c4fcf3a758d4cec508fe542b8bdab",
+ "content": "3c596d2cc26596e736ce8c7ce2d2cfe00dd04ebb50eed4fed4c71340994b"
+ },
+ {
+ "address": "1bfa31ab342b9c342dc9aaaacced7c9a27694faa6195682a9e7f5d47725d28bb",
+ "content": "36178481f5cdb487be6e5e341a4182a04ee3e664af3edb8d6b00976526c7"
+ },
+ {
+ "address": "1c1c4644ee795707c99a5c129be68474fb3dd745fdb80a0d2d1daba5cb50988f",
+ "content": "c0a010462661902d344cea0ba0ac25c5767d55df7b7ceea52429c200aed3"
+ },
+ {
+ "address": "1c3b709b451375ff28c48f0087532bde88d03e94d9cc01cbddab3d6b6f3f3f03",
+ "content": "51265dba2e4d7cc07ffec0c83e348d36d97574578acde4f3676a4601de51"
+ },
+ {
+ "address": "1c7b213b1e1a760554a9de73c533b342f10f577cb30d5868879537368050e8af",
+ "content": "a2a836380d191e5f579751dbe9ec7fb74ea4fee45cee75f093d5358f033f"
+ },
+ {
+ "address": "1c7f40a3f42a164172cef53aabdbadd78ce5cd65759bafa429ee40f658176f25",
+ "content": "5e52b3f7f7c26c6ebc7328655021d32691ccc86437f27bb548fcf3dadc3a"
+ },
+ {
+ "address": "1c935f625edd0b0863911ddf2271786b6526d64018b38a2acfa516ca697548a5",
+ "content": "5e00a4fcf8dee43bd38fa9ba421a67a01c04131790a213b52db410678c23"
+ },
+ {
+ "address": "1d4d5fb5150a556c8be2d31fc6b24b1ab6fcf72dd4ef1a35eaa3e30d66f27571",
+ "content": "37859702249ba34dee6b98653ad20c2a607dce0955b12bef3eb72fff20ee"
+ },
+ {
+ "address": "1d5f155a09ca40acd2a1456e85681ddfb1ef332e0da441664f768dea54a1c87d",
+ "content": "93b90006ff5979304c648b7c89c43f123a8e2b61f78e699d270ebc92f16d"
+ },
+ {
+ "address": "1dfd2e031072d197c58e188c2a03391c2dfa21d5d9ec8e17b798078f4f3075c5",
+ "content": "d19a6eade945c86c81700b8510a2c8ee0bd9d0e155fb452b31d3eba863fc"
+ },
+ {
+ "address": "1e6d34851c8219e3896eb0104e6f8db53a408690b647396627dcc568ef688152",
+ "content": "4966dd12f205219a10921f52d1d7083f8b82033e17964fd4eb7100eb5f7c"
+ },
+ {
+ "address": "1e7ce1de19da3e382463bfd3df3b438a7a640ce258e319ebcc13cfd67b6545ec",
+ "content": "29f3eb2c62b45ceef6bd58e02cbf14c75da0313774b394fee092f3fbd8c2"
+ },
+ {
+ "address": "1e8e82c54bc79ad92f94b0361b15153943fd9381421322c052c13ede739b6384",
+ "content": "74c1ead22d09f79e2f9719c14b5619bec1842f526929f992115681fe94f4"
+ },
+ {
+ "address": "1e924b13eb8f28b0f01fe85e327cf05c2eb2d2d3669dd1edba294172112fcc12",
+ "content": "119bff2067f6c5821354f0dab305c4f62e51029e6b45c7f1020dce2cdead"
+ },
+ {
+ "address": "1ec6f5d5eff4fb8f2678c543aa1ed7a5e0b62127553a16901aa7e38a5085450b",
+ "content": "42394e2c859b6f2ce10b0b10bcb72ee82084069d581816d26eb7cce3f6b9"
+ },
+ {
+ "address": "1f03b4820d57d7038abbd8ff53a31ae64ee737ce4c75cefd617356b1809d5132",
+ "content": "b0c5d44ee3068dcae2bf2b8ad843a569489a2ab29219e8bcdeb0d744ac99"
+ },
+ {
+ "address": "1fd579900ba9e5e7b1e77ff1ed42f9dee9d7cde2abc809cc2d7e3cf178f22f01",
+ "content": "188897a988349d3089624c019b12454656f61269ae6dbf0ccfa602c63998"
+ },
+ {
+ "address": "200cfbfc58853a8066587aeca17fc67cbe58f3fcfcf99e2fc33a22671d71b280",
+ "content": "a000ffc9164fcfdeed3f88d543c65ef7392f065d7180d3a89ce7859f2f75"
+ },
+ {
+ "address": "2062ac0820f0476d7e0ed9dd69d827d0238d359f37466c11c6096478cc507b72",
+ "content": "fb1435bd98f5116122a358e5d996fff5619594cf39974766dc74426cc44b"
+ },
+ {
+ "address": "20634132d14c034ae459a117c8bbff4ee5ec4fff5c66a6ee4988bd311da280e1",
+ "content": "e1ab4e3d83399df25d1b4831c9078e5c091eb5284c73e8963c3cbb1c98eb"
+ },
+ {
+ "address": "20680a79eba1293483b9b08c09456d1ae3b3fe6b566d21c55b5e810a5970f1da",
+ "content": "df48499e807e9c0c07e46a94bd15a55dd992f36374992a68a80788fd2226"
+ },
+ {
+ "address": "20683fbe4c59f5821466eb0237a12a501332ae1d1ec8f6609e1dc5aceb8ba8ee",
+ "content": "c37157b7f41ae7551eeebd0f6575447211db4536aa71d5bbf3db7216daaa"
+ },
+ {
+ "address": "20f9f640d7485eeadd4ec67438ab484f090549f98498ded5a1b7f2213b5d0724",
+ "content": "f5c43225086cda5b12191f57085fe36dd9269317960f8609d27ed16ae162"
+ },
+ {
+ "address": "20fcd4cfc9a1650433154c1a1d1d77446e29c0b7cac562b5b19fd95c0a19f5c9",
+ "content": "d10e02389c59b41cfcff41ed3522f984dbd104875de2b5d8d8f47fdd4539"
+ },
+ {
+ "address": "21211b6207f65f620dadc759c10033caf0c7d429bdb2cd60c485e2505d2c6669",
+ "content": "8450e0ba2374f141a0cdb83c580093329278d72ab133229bfd11edb22f43"
+ },
+ {
+ "address": "2135e23674ffe005e5f3bbe06039d79043bb35975001f0693866f3d565506ab3",
+ "content": "e6c2cd8a8abcbce49611793ba9d24c3cc534ecb0dc34f918c5cc0b4c393a"
+ },
+ {
+ "address": "214faa56193869a75e6840dc865faae2bc50024f9ae89b791fd2d7a3124ce526",
+ "content": "2c422cea585b1ccad04d77304755a9d40ea6f29d7c857e7a2a2946cb5119"
+ },
+ {
+ "address": "217173bc5b74f373f004cac246e7b0fd0d901a0553ba7cc678fe442053034aea",
+ "content": "edc97aae9d189aeecb4bbd87fd762f76aebfbae52e41d8a462caefcdbc75"
+ },
+ {
+ "address": "2199916a5a26c90ee6938e04c3aa909e2ace14e79fcf8c1fad7ce99dde0c81f2",
+ "content": "9e7d6fbdccb2bf172cf44f647773e6a04532d404dd6f910aacaf401b10bf"
+ },
+ {
+ "address": "21a05c66a63bd76ebd36775b9192c7b0b3a5b142de3ed7d99868c1fc73734c8e",
+ "content": "bb5f443781fba278cb891fdf78868bff84edf685e7fc0ca642865b1caaab"
+ },
+ {
+ "address": "21c187d1cfd67fa30e84ac199cfb252664f581e58777fd919209648aa6112ddf",
+ "content": "39153b7a7c92c0b43af345f89b718b042fd0e9e7e8fc2473e7f7ad7f6ce6"
+ },
+ {
+ "address": "21d290853c01781e31e803692c1d9fbdb1ecd522ed209da4af154908caa9bc69",
+ "content": "4b1333d994f7e6c41d6f8798499b095a73e0778f25a23395e0c5a926a1d9"
+ },
+ {
+ "address": "21e917e4607e9ea5d7fe8093c809eb81deff3d476183df1be0b2146ab084e30e",
+ "content": "10b1d7cb2f686a57d09f7544276f931b4e1d8d39de539a8faf0fb01faf24"
+ },
+ {
+ "address": "222d01fc4f8969ed5fd777c772216d3d7ce8d7a60f18325e53e76440852bfa57",
+ "content": "d6687709ca82b365288a04f69ab79ed91f9e1c8995fa5cf204fdf049a048"
+ },
+ {
+ "address": "224854daeedd6c4ff3471adf17c45f7099eced4c94e0d7617ec81f333bca131f",
+ "content": "e1fccc87c3c5a200e3938f0bbc6a8100caad38be027c955c6f1db03e9600"
+ },
+ {
+ "address": "22b7597b662dff22e34229602b0487544c93b3d1caa8393602a9689eaa6ae8a8",
+ "content": "9d0defaf8ed56a4c5b6b4a555f9b3c0815928760ce9775afdd642e1eaf8b"
+ },
+ {
+ "address": "22cc4448b28d798aac3d3aab05194998cab05eadad4eb56750545264ad2d3120",
+ "content": "b2ddb00931d64dd07a428733cb08f3ae64259148f3697622f79b2acffb95"
+ },
+ {
+ "address": "22f1fdb6a3804d7c4a6584530716be64711aaa11d6f5700f005a5a506ae0f9b7",
+ "content": "f3aa747b8cf623fdaeecd5cc3932b5640148b43d16942def9cfbbf7fab98"
+ },
+ {
+ "address": "23565662f30c6ac16ee4a494cbf0a278491ced0dc48029922b8eb70b32105892",
+ "content": "887296089a6e62eb04fb8e4eef650f236a0d7f249643188486b22376854c"
+ },
+ {
+ "address": "235f4e17aebf3c39122aa686b162c4c46d0808020a165edaf6bf4fba8834b6a8",
+ "content": "5f1f19a6efa45e89ce48d0b142859dff0fa97a56b9eeb71775beb59f7360"
+ },
+ {
+ "address": "23b1dd8a245eed907ff5c5227b335c9831f28897b9a694933bbb6aab1c53b18e",
+ "content": "a0fb1f4a2d048164dad0311fac41df012de36a50ccfe95c72702542f0ea7"
+ },
+ {
+ "address": "23b49b0bef74808323c7ac44ba4c9e281a7c267c00ad9d11e49223ee28997643",
+ "content": "fa2c7415a396cc4eebb0c68e68e4f15f88f1690d54a52bf0a801bdd888ae"
+ },
+ {
+ "address": "240a92f629b2312b2f0dff9d2852adc3614176f495493005781c4040054bf57c",
+ "content": "fde77807f76deb292a69a45355e59c4f8b81435dc844c323acc5dafb7747"
+ },
+ {
+ "address": "24555fda91303e4f829c995479608c5ca8b7a2e1c4e059e5c54e7abe297b5ea1",
+ "content": "d60eb462c51bca0a869c50bf08502712044501f37ae75b59cdfab7653193"
+ },
+ {
+ "address": "24c7a933764f79e1c2054c8497142270a85c7ff3209a3abd1b322b02d3858794",
+ "content": "0af4ec30eb835579c448e52e7632e15fc5ae2e6f67dfc02bf879a7d7e911"
+ },
+ {
+ "address": "24fab55efdd1a7a2ea906062adb9f87fe8aba90029e075d174a57cf11d73ebd2",
+ "content": "7950c80ef6f0bfba5efb2aa4e0b6b67fd69dce391764b23f5e631dfe54c8"
+ },
+ {
+ "address": "2510f0260be2f61773d7ce9f956c39428960e2a08135683c14bf680f06e8eb41",
+ "content": "489ecaf7ab382309fac41a2f5ddb955975d54f963390f9925e8ca51c77da"
+ },
+ {
+ "address": "25b1ed2843d8011006ccc095c74b924b1dc2e2927d43c7fee1dbf1af214b2d7b",
+ "content": "49004f7d4c687ee5bf4f6aa0d6c8f949b7d2abbb81027a8b5cf1f977a00b"
+ },
+ {
+ "address": "265144514c1953633f0210d447c27826da51faa19bf395020b3a49eef7c3878a",
+ "content": "da55dde81672afae7340e020e0769d4b8cc81eac6eefb1336fe2fd5860b6"
+ },
+ {
+ "address": "26c158c5f9cc063c1322163382b77ce7794a5d2df31d39671667df3963670bca",
+ "content": "8619d755924589256ede04c496b2a87f110278e4eca17fa5b978e45dabf9"
+ },
+ {
+ "address": "26f3a2e1726067c9686455844465a66bf4858ef44c293f766abc954dd8b67181",
+ "content": "c4f0ba152a35a65240eaea82974a914981c1d5dd931de0aa9f83bd65cc6c"
+ },
+ {
+ "address": "272d2c31bc1187bec4151de519924b19f7f9ea75c87b3dfcf59362e7e612f005",
+ "content": "ee668bf68bf4b492cac52fd4f78fddfdf48dd3f763c06d665f807c6d8096"
+ },
+ {
+ "address": "27355b7c9a6413cfe309ca25a7c34a2bd349cbd4cf6c4bc2652f5dbd24d411ee",
+ "content": "170267f3cddc2726672242f9965ea0e67abff0e7fe65720e4cd92c25c074"
+ },
+ {
+ "address": "273b2275d3595d39720bf8c65daf683a81c8507c17e5dd099e5e80a5be48a576",
+ "content": "73cf8f2d4c068c1545fdbd919787ad251a523be1d1470da239e579104483"
+ },
+ {
+ "address": "274b57a0c5f98515eea69d3fe7ad4b8f47f449bd87061cb875a1544055e473a5",
+ "content": "a327fe24af8c45f238cce24dd4c8451f471bfc7e82297449a8ebae4a89aa"
+ },
+ {
+ "address": "276114469e13e2dd3fc8106a4aefadbc884460a145a70ca52a694a3613087a21",
+ "content": "cbf77217747a890db96c382f88d6dc24f6e3ddf9cacf0fa6437aebdc1a6b"
+ },
+ {
+ "address": "277075ca40ce80f7af3633d55b9a36eea6c9a62d5baca59b0ee9649d166b0336",
+ "content": "86274bd20560a640e90c48c9a2b555d1698f057953b66efbc08e62ed14da"
+ },
+ {
+ "address": "27bcfd94416f55bf87fe667df151637644b730a42163f9141afaf13ce659c712",
+ "content": "3097cce6553715d89e91205d0036e5f4930beb586ef12a00c51eeaa24687"
+ },
+ {
+ "address": "27c747878e7aea9beef1d7ad24fdfe8991be9eaef990f9bce2ad1b77b4f30221",
+ "content": "8854416bbfe73aa877e6c19aa767e9d902da36b79f403801b851e859bcfb"
+ },
+ {
+ "address": "280b8a06a48f45f9fbe2aa2b8f38b5011bf480f5bf34fdf09d314b3c97977125",
+ "content": "395cf2c72391688ad9d4657f246c22dd4346cc89b5da57c76dd2984096ae"
+ },
+ {
+ "address": "286090e4683cf915800494235e292b66d89dce41843bda1f5cefdc7e457cc4ec",
+ "content": "47ff8c23e98a7d9d2663fba8923dcc546cf444bcf6c187fa7da61c0449e2"
+ },
+ {
+ "address": "28e57a8b04cc5ee40b8b384e031cc2bcc34e36944e07ed8a5a7869fc318141d0",
+ "content": "a0fe7ed82f5d85c6a764a7e94a2b1768f6e72c91155b91ed2b4f10d09029"
+ },
+ {
+ "address": "28facd022f8dfc5e0dd6fe63d9b0eaf70d632042e76f09c954a85b6abb59c387",
+ "content": "d88b2a8dd4802f2e1ffed6b67ec327143e905e15202edf0e3386f1b67197"
+ },
+ {
+ "address": "294ae17edc691f0bb77b7f7304b1e9b8d49b0e67f508002015814ea444da6b2d",
+ "content": "42530577bf9994a341aa77f32f7a14baabb82792c96502b2f47270587392"
+ },
+ {
+ "address": "2a3e562863bf67de3c46925f726b181e1a9ffb1a803c65fcd2f39a37f8682816",
+ "content": "81aef2b19b30783ffbc21b08773a6fefe340af2fee5db821a0a563f4e36d"
+ },
+ {
+ "address": "2a76d4319cb87cb98d3046296de21edd8ebd99a16122fce9927ca74045a295ed",
+ "content": "a6d23b7d74f7860e46c28695ca0cc653806cf988226738da72af4cf9baa4"
+ },
+ {
+ "address": "2b193990e9477f1c4e905f50b6d6443437e77451eaa11f0352b0a672e1292350",
+ "content": "231563b2f32eb6c1d6827f1b79bdbdf40e570d3b9a6869d576fa15c15d74"
+ },
+ {
+ "address": "2b86a93bcfb98f49703c23d44a0fdc4469f15101374117cdc87ebb7cd3164999",
+ "content": "a6238d7b0fd313518d5561426ed0714f7b4c52ca8996023211702381015f"
+ },
+ {
+ "address": "2b96d5c53b830efea00c4026b2a0ae3b3d0d0ac346633ec34c3e085c6ab074ab",
+ "content": "567caebb906c380c922cba6e4b6aa28afac3eaa645d6a32db21f6b3a0f27"
+ },
+ {
+ "address": "2bc6a8731939d180c544785012cbf19147c75c39c4e382c5c689f91d72c06520",
+ "content": "e45c2d636c1a839d662809a8d311e70237729b8bc5fd6b9476c767bebfcc"
+ },
+ {
+ "address": "2bd099d04d16db801b8338fa43d4a472cb2f34d8b63cff371e8d65e263aa8b46",
+ "content": "fed94333a852a7782fe7b1ba1df837597e359e18657ef91fb859577910fc"
+ },
+ {
+ "address": "2c3cf47d25e8fd3c28b58fd02db352e200d51b15b2ca8442850812afb4560011",
+ "content": "cdc51277e3cbeb970c114c78bb40461efaefc8f69fbc5efb4debc3bee7e9"
+ },
+ {
+ "address": "2c53a77d7698d7006a1140eede079b52327a905daab3908cd9eb26336a89a134",
+ "content": "6003a8cdac0708e13e1c984adfc8a00cfbaca627900d903133e8c458d6b4"
+ },
+ {
+ "address": "2c7b97443b6f54bdc968ca56bd50a789f5327f8fbe91278bc9e861228df85e53",
+ "content": "8bd7a8a7a12dd7f044fdeb9ef4e0da8c1d6934c3d1556db17e79841452d4"
+ },
+ {
+ "address": "2c8b11dcdf967e64bc0ffb1643ee2c5f3387a3c24868d1545cb1c83a34335569",
+ "content": "fef1663effe44404c5c61b1a7b27b3718ad730310f31539f12382442d886"
+ },
+ {
+ "address": "2c8d982d6cdf75e4831a734bb3fef3a25aab33aec01002bf777c6ea34355b32f",
+ "content": "01e45b357eb1adfbc6fc604a2ae371f9472a6a66a10891e66ecc18e6c14e"
+ },
+ {
+ "address": "2ca205a6c384a2a485868ae58f35fea90f264805693b4565d9e28163fd21f67c",
+ "content": "fb70252c1bb361336213cca2e3482fdd186536d2b313412c91ebb1031f5b"
+ },
+ {
+ "address": "2cbd4444c9965d56f25997aaa9a31ccb6a03b9e423d9d8b8b759044feb8a394c",
+ "content": "16486724548567a52b4155d57f737f686c6d50f87edb069202479dc6dca1"
+ },
+ {
+ "address": "2cecb062143ca9598951cda7e1cc19000b1b480f53bd81b12a8f6407b6a7b268",
+ "content": "df78cb30664a0c9f9709ac9389defc1e860b900fbd3362503c299b962bc7"
+ },
+ {
+ "address": "2cedb34c9396687100041099f392a2e793d10a5f51c6fa4e6b637fd498c628f4",
+ "content": "8a6d20632e795658fd461fe0827a2e1be78cb08fca8aecca695e6a5847a3"
+ },
+ {
+ "address": "2d3d0a95751452d0d3281d725ee574b212be1d3af74e5b1aca1443434ff59fe3",
+ "content": "9b09d29646bd5c1cfd68483a06d68079aff7b9ed14f425ba93b6a73bcbb1"
+ },
+ {
+ "address": "2d5d1155ebc92e1f04e40e598d97590656d3fbbc3b6ecc0b643e2353d580144c",
+ "content": "af7828447376bf73021121806f6c599e09e97e682da444c374acb57bc5c8"
+ },
+ {
+ "address": "2d8689f07f0034d2081ec277f63aee3c7114d3f85890632e18e46a98c2c6c76f",
+ "content": "7d13c968080fe43f3a4c344a633534f8fa69a80e4bde1441187f0da70aaf"
+ },
+ {
+ "address": "2db73928adc345c4e4a71d923e7591f30fb3187f8a05408c2e90263a6b943285",
+ "content": "759c94be630cd9bb83eb571b753f6976137cac0f87908c7ab0f8bc6de9b5"
+ },
+ {
+ "address": "2db94cd369468946c2a4d0da6a89030185ddc9c9fb90ad98965049614f9ead3c",
+ "content": "531bc51b5f3ee92628d056b84abe1840c3468f6a2a836fd3094ff188aaec"
+ },
+ {
+ "address": "2dbbd5437ac799dfb0780cf73d494165bb08dde1b7c351b0bfbf5a955ab3af1f",
+ "content": "7a97dd1840e39309b8c80ab773d6c8217747da272e7ce7e746b75d76f635"
+ },
+ {
+ "address": "2dee3795957c93ee2c4e782c80b19e58613643bdd103a8066bd753db19b56a27",
+ "content": "d2cb7a0b69b5d4822c6e9b534c6e495e52f80a8ab2b565f54f65aad63674"
+ },
+ {
+ "address": "2e098f88e6683c6691f2f0f9d333587dfda798afac207bb9eb458ac0b7e1ca11",
+ "content": "f6dc018a06e4935e9ec476b1d919c6ce59f73e0daaff9710a07584ddadd1"
+ },
+ {
+ "address": "2e19d89d21eb095cf4751c380f0f32018fba5491fdc148332297ceea30f54389",
+ "content": "b81dbe346d89d66ff04fbd8f03b4cfb1aaac5cc369030bc1ad713831632f"
+ },
+ {
+ "address": "2e229723517ed9d73506fd4e758176193031850f9ef60c5089e119a45b8e934a",
+ "content": "c1c0e5e8cdb1c42a78d96b5c4387b8c1779cd445f5f7edd0c33a54fcc6d9"
+ },
+ {
+ "address": "2e2e780cc99fc4a02951115a8436d250eff246e252970ec57a9bb7b86b767929",
+ "content": "a1c5e06f0b1bc846771686eae7ce9ba1ad6bb16900efd8abe55f86f250a6"
+ },
+ {
+ "address": "2e49592155584f87e868b44d6d9664d5c879c65dc8e3fe5f6634cce36fdeaad9",
+ "content": "7a5d7ec46b2c38e55884cb394f126a5cf64fd4df68bc7cece5e82f178d70"
+ },
+ {
+ "address": "2e4a67a0608227b07a1708c614bfa47b5f849114b4ff133198753918dd8f28c7",
+ "content": "51e699a20dde5e6e062e65c2d2b47ccc438464525aecb730ee213e2eb0e8"
+ },
+ {
+ "address": "2e57cc26bb2f9b8e93fdc78b1dff6d8b7a37a64f69b266f8f56268cc17e74d5e",
+ "content": "b206038ef994a364105b0e46b463927088da3f8790171014e32de852ac15"
+ },
+ {
+ "address": "2f57b4c4d0b699ee868f6fb7be39db1ba00907fa881daa47d46c5eb3e8e4c541",
+ "content": "d101020ae386c2d6aa5073e09530d7ca295f923f39dac43fd6b23cdc6205"
+ },
+ {
+ "address": "30403eed446f3d0e075e48d5f918217019effbabbc3b8e62899ad540b83c981a",
+ "content": "001228ad2bd36c94ffe4aed1209a49254047e28870e1320070d4da783eb3"
+ },
+ {
+ "address": "30c637567a9ce8e16a1170cc719094d42c8d41b40c28a41596c1589b319b13ce",
+ "content": "1e46f84a1bca2adbe3e651575d2d63c10ae54c5f45fe7bf9f071f2aff35c"
+ },
+ {
+ "address": "30cfd958137a4b88ce4a3bd09d207f79327312f202c6692a6495ea8f835ff852",
+ "content": "476b3d73e83c4232c2e135189c68666204336652988726e1ef2eba25a795"
+ },
+ {
+ "address": "3104201cfc2b24d7a606cafc1a8801e2fb45c3ed96007fcf4588a113121ea880",
+ "content": "4c9d6e735a48ee0a1dfdb35564045d472690b174fedd4790c7fe8e98206f"
+ },
+ {
+ "address": "310ecc17aa9033023efd15abc6fcec39230f7325570c62b7a3c6e77891c18265",
+ "content": "04be7c9d006a99ac659dae0eb4a31ce1983a4c3c038a8028e91480531cc5"
+ },
+ {
+ "address": "31195513cf18e147dc7dfa40ae5e5ce9dbea30584f68b0c8a801f5169e3bd054",
+ "content": "9386c7238e83e392507ed5df9f2a04ce02fd5ad7db761fbc5cf306024a5b"
+ },
+ {
+ "address": "313f17d1223534c4223134e30d92540b53105d90d18972526b7a0b2b223e965a",
+ "content": "3e636ab2f1357953144ca70f84c2a5b6c4ebf6e250046731ea2cc904a69e"
+ },
+ {
+ "address": "3172571fd351a96acb815474d46334adcf3123cc5a88ee00da62cea1fb395b8c",
+ "content": "af53e7ecfb2c4fa6f8da001c38fc5e79c8124ca42107706fb6de853fc731"
+ },
+ {
+ "address": "3178ee882da681ccd9dc3ae7c79cbb8ba6464563f0f138967353dec2af7c1df4",
+ "content": "62bbc48c161fdd7aca60abd9f84ddaca826f907acba7bba7f7bcdebf8e72"
+ },
+ {
+ "address": "31c1c7e14b157bd78dfbcea3084117591e9d1bf905c355759fcb08be976f7203",
+ "content": "1ec2d7e1c1ffbd9b74890122e01ba41b068a28486a28e7be1451af7757a4"
+ },
+ {
+ "address": "31e26f135022c268c3592d4f1283007265a256729fa339dfae596b2d1d79ad40",
+ "content": "175f6c9fb0eed912455e9bb807eb6f7e95db005d1c9806f07eff7d6c84d9"
+ },
+ {
+ "address": "322f164fe408e6a04e2632dc5acc035bb9e22c7a84653c60dab61df70a75a6ab",
+ "content": "fc6d344c13e16d91898353bdeb6f2f4d4884bf5cfa69c78175d36105b2d6"
+ },
+ {
+ "address": "3248301bb73dfc184bcea2ad324972503afa7cb9f3464885d5c673032be3d577",
+ "content": "5982c484fdba27aac8e9eb6d9c9048dfe0a50604466479e6b6a22e91292a"
+ },
+ {
+ "address": "328721364a1406fe21c6c42efb723af94059a3ddce86d42e887271327ee0d3cb",
+ "content": "748dccd812c9a0b655fc26c7e9842acf3a2de084c300c2a84ad64657cff1"
+ },
+ {
+ "address": "33357f929bf37ec7a6d8b5c8521d730c8193cabdc1e849db427b973a39a6496d",
+ "content": "6785617feff942040d3a35415763b906b1e6a76f226c7fcddda6bc68f3dc"
+ },
+ {
+ "address": "336f262eebcbf7e1046ac8d773cb56c87f33a9982c5dd21a85a15716a7b7057d",
+ "content": "6ff094aacdb8d99081e67b6b9741a8308ad7a37811db706ddf5946183e78"
+ },
+ {
+ "address": "33bb317ea2f455cd24ae74330f377bc3aa806d9fc109ba7ffb98e3452023afc6",
+ "content": "bf7db5d773d0c65fd5addda923b7992285d942476847a903338dc3fc43e2"
+ },
+ {
+ "address": "33ed35ad6ab4f39d22a720776aa33b8700a7f2bc32310d96ab6db165af9f702a",
+ "content": "28be9932261a4ae74809574240d257f137be81d88488dec345aa734272b1"
+ },
+ {
+ "address": "33edefdc298be437c0e06e12058b8cf195b7f41f922cd4fadd442d0e52a73507",
+ "content": "5dd28ec6cc1ed58f5cf51517443709571980475abac3ede0d91cfb1553bd"
+ },
+ {
+ "address": "34086e45ace31962524c5908308a75b4404ae41b7eff87d25a393e62693fff26",
+ "content": "13c1331b02b1338bee1664aac03e97b5f5305f745f9d879e56478d41ef27"
+ },
+ {
+ "address": "34494bbe290598da76cd2b60b28fdb540eacb9bb7df57b5e3c0ed4b67f63cc0d",
+ "content": "c53844453d0a69e83637b93c57799f4c8f39e5532a5b77f3bd411fb825f5"
+ },
+ {
+ "address": "345ef60f8bce1e82f696c0f9e5ecf4468c3961393fd2704908e72bb2554fa13f",
+ "content": "85971b8cd20fe3b683257e65f683a92a294a30f8a1a3a15c4fb01c33b77e"
+ },
+ {
+ "address": "347ed45a9501b731413caa185792bd0368d752576d1c34e3fa7b17766d9df917",
+ "content": "fe2d426d7c40663f98e59db0eba78b60fa128d76d2eb0ca0fc3782ff0627"
+ },
+ {
+ "address": "348fbcbd5777d975101f3f09ce8452f1f3825fb285af11d0dbec7fc25977162e",
+ "content": "3b6613530ab40f653eb6dca7a170e66869fe3245a65b1d772841fabf800e"
+ },
+ {
+ "address": "34a0948124c7281276b55d93e7fc305c5943d1fa871521258c102ee4484509eb",
+ "content": "87c75ff709f5a6492283b91ed9b9c7819f7ff33b869e3e6d5236817d4845"
+ },
+ {
+ "address": "352e59775425b43b480a84cc5a4b128d0c7b92b193b40ac7d0a8aab8d204fde7",
+ "content": "97f8376dcacc87be4c242d410ba86db7e115a11c9ebf96837922cf65a28a"
+ },
+ {
+ "address": "353f68110636fd5e2f055dbac8258dbfcac162a583b9b214aff293ab2d5e13cd",
+ "content": "dbda8b842135d995e6f23aa270be94e53cdf6c2b0eedb299025498c73dad"
+ },
+ {
+ "address": "354395044efc86beedad09eda00ee0a97b658363e18fa742eead9fb435b7bef4",
+ "content": "5744fe8a4f47853b7fc5e3ee6d893908c17181720e7347cfc0510043d554"
+ },
+ {
+ "address": "354cf281fc96e89955725b2f437ac47a94e4b5441f25e0787982a0358901c8e3",
+ "content": "53ffeb12963b67bad778dabe3ca82593e9bbdcb5168104eaf1f883e451f9"
+ },
+ {
+ "address": "35c50846e4d012fd7ecf35e2689360b1e89e24506ee1e967906a6c7eb1199947",
+ "content": "644eb05e0697fdb43f70985ded90040a63ebb18bdc7db3b97487ce95d8cc"
+ },
+ {
+ "address": "35dbc366ab2b429a89b38dbb914463075f2992718cc1463c90343874d910f864",
+ "content": "265cdae5b4d43ddba5bd41dcd87a136b351a6e08e4d76cfa8e8b4d9e4efa"
+ },
+ {
+ "address": "35f9a81531d91b79238f97b28e9d33fdb65a63300dc9c53ff7a414760315af8d",
+ "content": "847df3d0bbad2e8f77a7498b4654cd674bfd1d204b874b46381e97db3437"
+ },
+ {
+ "address": "36177dc02b39dec25b9dffd52748d61d2559eb08e7ce62e12283e0413a9b052b",
+ "content": "d42d756ba54c33bc2a6824413830006bdc96f9845da37d50bfcf96540701"
+ },
+ {
+ "address": "364ddc4e4eb3b9940b1bb8f9ab67e8162bca8840f4dec6d370abe23be0a2744d",
+ "content": "e4254d35aa93a1a931956fe8127e56efd70132639ee04412c95604724e67"
+ },
+ {
+ "address": "366beb1a48fac10fa882fc433f84b39facd3e0bdf55560ef89a67de9787f498a",
+ "content": "d2a2bef83a26e5c90ed615fbf16762228a1c4793342b585ff9079e9c0baf"
+ },
+ {
+ "address": "36dded1410fc032ce50df9d718e27961372d089da03ff74996fb53bed0bd7417",
+ "content": "1875e78c45b0cbad25ffbe8a67f02de8604111cf5812a245c8bb7a6c85f5"
+ },
+ {
+ "address": "373719ff49359fc1371af011324a09ff4e6e3d7d3da6b7384a5e0f7268ca7b3f",
+ "content": "3ecc3c099c946007adc628facfd4bc1b536eded60484b087b6d6f504cebd"
+ },
+ {
+ "address": "3738fc6ef8ffa932ad3c850a25245ea4cc5bca6c4b314971d629e0dad40d0f17",
+ "content": "3ac88a7e95210f68c855a96881d43d20fa3afc29752f88e68e64a86b9171"
+ },
+ {
+ "address": "378608b1231d64937bf994af32e37e31ef0b8779dd41d4815a86056f8fcb83cb",
+ "content": "afd8ce535d15222122c2b7b6bce2cb4660a260219e71db3bddbd98853369"
+ },
+ {
+ "address": "37a80d321fcd17c52e558825789d7f7a397414195940e0f2c32f49b2fdbeb3ec",
+ "content": "69ea7d4ae81768f1fe24fb97e804c06e60faa68839ceb0ea1b193166613e"
+ },
+ {
+ "address": "37fcddb9d43653eeb7bb9e916077801902dc5ce505875fccc6c87f3d4557accb",
+ "content": "6dc0219774037e961d651a2e31465f7df08ff674a83766e320f9bcbaf55e"
+ },
+ {
+ "address": "380cf4aaef14f1c01926d52de9ae6f337da6b7b5335f519857aa7e70bb31d0ce",
+ "content": "073b0b453642174fecdc0de564687862bfe2d3247e1894f63e9c365a57e1"
+ },
+ {
+ "address": "381567cc53404681143746cb277b132dbe403424306dc2b9a06af4eaef0542a2",
+ "content": "aebf2f15b308266bd819448c0ea6b25dcf5c02121e93540c1044a9e0f34b"
+ },
+ {
+ "address": "38651e9f7061b1dcaff7c74da2afdad2833456ba8fe4d93ceba7f9f3f828d154",
+ "content": "e4990282a97515fe0642dfaf57f9211a0b7d1420fbd7aa9640ac804459bf"
+ },
+ {
+ "address": "38d39c575112673186aaba469356725dba1397de5c8ceda6719a6047580727a5",
+ "content": "40cabfd6acec3b2566073fe21011aac5c2482ef694fe5e8d8c27d779b208"
+ },
+ {
+ "address": "38eeca802f10eedbb80945071dcb7004a73625a163817ff4b80db102c617dbf1",
+ "content": "d9dddafdc56e2afe58c16e02a4cabf5c37f46e546221ab31f34ce4e9181c"
+ },
+ {
+ "address": "39671d93cdf0374f3300671b662e30d68cf8f4816d7470076dd95250447969cb",
+ "content": "6eb7d135858aeeb4d07863830d85d699e8b831497671b54b904730471b18"
+ },
+ {
+ "address": "396d5abcd1ac10fb1ba8841b0c55fa5371d257703022c922270bc64124c6ce9d",
+ "content": "9cf4f9028a440987cc213fe7508c3d0396b776facc345d76993246c2509a"
+ },
+ {
+ "address": "39ca9d75b35fce19aaff39a38a61a0d3423e051a7c60a05d869cbd44a9b2f427",
+ "content": "b94ac939e26e0a0b99dbede68f77c3e1b3621038af6fef5d97e62e56e266"
+ },
+ {
+ "address": "3a012038c812e4c6105d2656c1e03e8a51040086a5d38b86ddda7fe865290446",
+ "content": "37519e781889a45e9469123f1219e30cac5b79189a0e8afabf443a121ce1"
+ },
+ {
+ "address": "3a766eea0bab781b6b3082740a2a42bc15dcc1b47b5196382e1f1d936897329c",
+ "content": "c73cf0d842637edae4fcdd2f14cf8a64879791f432f0c462023b74a606ed"
+ },
+ {
+ "address": "3ad06f637f6b4eb84bdac631aa31c3c859f1b4b5239dd705055555d316818c4e",
+ "content": "7b98f6ddef502a574a095de259cf2bf18ae458796257cde554ae592e0e17"
+ },
+ {
+ "address": "3b0a8b728c0dc8a4f397e62030296d1d07f936829a1f2dc818983ddebc0d28f5",
+ "content": "02f5810bb6325f8ded8ce786b9f712f70eec4279379fe736e9899f2dd50b"
+ },
+ {
+ "address": "3b821ccee8dc8941c4455e5b14af8139eaa0566152678670a0acfc4ed16deb8b",
+ "content": "525e9a044de3f0c2316901803f298b9d91c18dc292eebd64240995be5519"
+ },
+ {
+ "address": "3b8dfb0f421c39bc82a6e7e55e33cf64c513864b43814e99f798482358675b70",
+ "content": "9eca4d267edde804683a058b1aab3fcea4f2ea08ca2cf4158fa9a2776d40"
+ },
+ {
+ "address": "3be168ce1c0cbdc0ecc00bbe9ed765d6c0e16ef4fb3af61aa26c3eacc96e2ee2",
+ "content": "e219f24cd38decff75f156cd4e5357b7c17634e83b9b7881aec444b31f09"
+ },
+ {
+ "address": "3c610c95dfac92d8e961a80046df1d24861b4e34f12e0b106a93d38d31774015",
+ "content": "428c7115f9b1cfaaa5e0a51cf6f2e6e0583929a1e98d6ce7a16caf8a5f02"
+ },
+ {
+ "address": "3c87718b62c718cc960a76b7ba9bedc362a2a69e36b99ba6e969fff97ec4a742",
+ "content": "81e4ac8843ab3785d4bbfc01cbbe0d99820dcdfae602478ed2d6f630801c"
+ },
+ {
+ "address": "3cad535ba18947a0f8ef18a137716e3fc8c8188e143ee77f71d49a4f9e73464f",
+ "content": "4e57ee8e6d42a3331e023d181dc601f734f80a4a8f6e96a0dc9a9d9b4525"
+ },
+ {
+ "address": "3cb6bb10fbe58277a9e736249a0664f309b209ec4c60bfea7c8c812989dea5a3",
+ "content": "48e7f5d59e0c4c315f1951eb9d2bd13dbd6afdc13a9bab3cb23391d4435b"
+ },
+ {
+ "address": "3cd7f7b3ab486e4e5b1e9d381a75d4034b9f5d024268b43dd29fe6341869237f",
+ "content": "5600a5ad2a064812095059d522e5fd91b3abe62503ebcbe58a76d00e247c"
+ },
+ {
+ "address": "3d29be84605169ccb848c54225ae6434eb6dc5c80a820929d1d649648dcba099",
+ "content": "a276a35d85acc73513d14c5334fd32cd7cab5d3ed3fbfa42475028a11400"
+ },
+ {
+ "address": "3d9c2809cb28b621824d19bb375c5cb8bd6d12e31fd4987b3766f1e06a3d5088",
+ "content": "7fefd4182cb30ff87c9eab1dcdf01c9b89c0511258addd1a86cb241dd0f9"
+ },
+ {
+ "address": "3da54c9abab4de933da171f747d367cffdca3b06c27a970db58c25ec48fa006b",
+ "content": "2bbc749be87ec082d8643f88b82b91521410fe18d72fc3f6b2ca29c7a5db"
+ },
+ {
+ "address": "3dac34fce1ccc779492094ba86fe2f3908489cb687d057f3bb63b51376115240",
+ "content": "ebf63bd61a0381e12a90d2c04adf8323bb7650a5c7bd0fcc5db397fc4122"
+ },
+ {
+ "address": "3dbe0405f1b9f448dd1124288f0914cf1c9cbe192b3c8452c5a77125c8c7bb2f",
+ "content": "b4817db64d69cffe19f8d33d669b294207c0d284ffac729994e32318a7a9"
+ },
+ {
+ "address": "3e61b716a9308675b713ea005697f9cb07673f7583a71e1570b61d64c3317aa7",
+ "content": "0c0293b88522e694ec69e3af768047c11147d9657fafcdcd345066036147"
+ },
+ {
+ "address": "3ec1a48445cc3d39cf8587b61a06be003e0f88301b6a1ece30fde3bdc7471e4d",
+ "content": "1babeadf7a9b501df1b43f5ac4d32bf1273b0da5fc7a8a22afe936660987"
+ },
+ {
+ "address": "3f2e3713861d17eb61f95858c3808479bb3e55299c0dff02c3e7e18f1eadf0c0",
+ "content": "36570d65023ec5071217fc03f609b2143973e3464d0d91808a37a58c72be"
+ },
+ {
+ "address": "3f97ab28c8c0dce5a70a248413b6431b23fd36281001f9dc77dd4e4b37964b4d",
+ "content": "17e8621624b2769c7c266b1bd4e14e7fd938cbf8cb37b82f88284e6c21e5"
+ },
+ {
+ "address": "3fc2294e5342cf3c32710aad0750e6d7f66ecc5065eccb0be72617f91fb9b29d",
+ "content": "5d099386bdb8dfab88778fce85a7226591dc4d621022cff2969ef6192020"
+ },
+ {
+ "address": "3fe44070db140fb67540686a0f49417e53ab993994b4d433da58d14d1004fa0f",
+ "content": "dd93370637dcb8e1955362e3317e24963f0f5d7f327139bc3c57f7c28d0f"
+ },
+ {
+ "address": "3fff495a5695b95076cba4730386f2806ebc6939a208b768413c8df528fad522",
+ "content": "331ffb22fb9228c23f1d4c03b9fdc1e36c1f26f1b4c4656ea324572e9784"
+ },
+ {
+ "address": "4012d7a684ff924facecb5a367313cce617820680dd01f801b1495912def2835",
+ "content": "cf0f2b5ddba723f65c9f55574748d56537abcbc2e7a8113fec48f583ede2"
+ },
+ {
+ "address": "40b8423e5f992156ce1f24d97377ac2d5e49e99d7954e1fbda63f719eb3a09eb",
+ "content": "1bac7547d5dd6f3ae3ecca93e84c65199e975798c236ad6c9cb2b5786dac"
+ },
+ {
+ "address": "40d3ca251810dceaf82a49dae997766523cdd4cca08d93aadab84ac48344ebc2",
+ "content": "74dc8cffb1bbf59be7318d058ef27aced4fd925fe5a252c60dcd6a8cfe07"
+ },
+ {
+ "address": "40df52aaee6c4f0ac2f95c42fc246e9819da50a6f03f006a644fdb5a3914e3ef",
+ "content": "d7ad028ecda0fecd6929f5394a9a26b89e724937766187137c70aca2373d"
+ },
+ {
+ "address": "41dcb16a2c966fa7942a65a5365d761dbebe0d9c45f99883e51fef4882ba92b0",
+ "content": "5dac486132742371e92f24006649763665f478dd8625dddedce52107b050"
+ },
+ {
+ "address": "421a40d30f387a3ec2bb7d6bb084464727f012076a425e8f3873eca0ed4fe5ec",
+ "content": "20c103b5fb35e288a2a04ad2d143ac7a277a02110d52b69b4469269ec28a"
+ },
+ {
+ "address": "42c584249608591464ad77510b300a5cede262f6afaecf0d6b37cdf0913e512d",
+ "content": "965ed0777a9316409a954cb8eca1742da217f6d86c6bd1247e76f049a408"
+ },
+ {
+ "address": "433f87b29a84eb6f76d6f2b34a98b1fc81c1b150d521980b997e04d11b42f573",
+ "content": "4e73b1588757e97c1c247beaa1b8580f70fef6e42279b3c9dbac6e466212"
+ },
+ {
+ "address": "4373f4026c7598d656dde23150ce9b03e2a6b7875b43926347791cb72555d2b9",
+ "content": "00ec28486d17ce5fe2497bd545462be5573538edea26b7998cf003a3f8cb"
+ },
+ {
+ "address": "43b290a794acbecc91e6e01e80a88de4286175ba4a548c07f1dcb26cae032b32",
+ "content": "502bbaf22ab9c125f6a6a58f3e8bb77b226f0a67c49690fd9d6e98be9f7e"
+ },
+ {
+ "address": "43fae262115e5a57e7edf2adb14c5a062cbe77e22d3fa0c66a3884d95297e55e",
+ "content": "d774aba8e4f3faa9c9304a752f0d4c5045acc783b3d0ef458d1f78c0f270"
+ },
+ {
+ "address": "442110136bea51caf01ecba5cd6fa744a87f3a9a68a18a2857bb22a239ab0277",
+ "content": "3bade9aeca23a00adc701a3046aba6e9092d99cc6659ec34fb305268a3f8"
+ },
+ {
+ "address": "44aa703bf80b4f95a14a97903929184dd2d111a7babd06549669d87e8f014533",
+ "content": "2fb582b2fff29c0842c0a177580024af4fb0fb315e36758296c446755aa2"
+ },
+ {
+ "address": "44efb60da68c98277c7f0b05e73e03f0231c1923925bc442fd58711ec026e60b",
+ "content": "e56b9ef0adb33e0e4cc0e638e4fc04e217f13d48b9269d69e222a38e6a35"
+ },
+ {
+ "address": "45335f6b9fa73ad49f509131b61a20eefbd27412c164228d3224da16a9a8a554",
+ "content": "38f47c41e260ce22aaca4f0ed6f7df75f967aefe9d8cebf165741ee8374b"
+ },
+ {
+ "address": "45410abaaf1dcf370b592c7ad6266439ca170cb84395ec242743ca986ebbab30",
+ "content": "9daba8ab4d4d58f9878a09ec7c3d76885b26e6c07adee54d634f63f6459a"
+ },
+ {
+ "address": "456f693bff32b0bb61bb8bae4ce7edebbe2338aea93e483d4e62359582f64df1",
+ "content": "f2cdfa57c24b1daf05f7b7f4af4b373f148c5e61f265d4da95f807b64a7a"
+ },
+ {
+ "address": "458ba6e61fe52f6732b635a37c3836ce77e863472cf21af989c6e4af02864997",
+ "content": "a1326435687b485ccb7fdb5df078082eb7eb76d2ef1289bcc52fa666184c"
+ },
+ {
+ "address": "45907b1baa72f41972422658659f356ce0996e4a0550a09248bb66e6b77969b2",
+ "content": "2697f8547770fae224b59184c0aa268a00f99241ddce0bbc534e71547038"
+ },
+ {
+ "address": "45a58a340166e3001dad4943e2e606617c362572f38bd1b8412a82eae5c7e7db",
+ "content": "ad3195b30c0b8d119f755d6ecd21fc006ad2bcf68e672be330da2939dd6f"
+ },
+ {
+ "address": "45c3454dca902b5f5e18a7c71a1203feaa69c4ec73ae9bdb8d0ab3327c8ad0a8",
+ "content": "14471b0b68b3973a46dc520ba7805cb1a87d7f92591fdad52ec895e47f1f"
+ },
+ {
+ "address": "46ed8937c2341dd018ef1f0fab9bfbbf07e1f34b8491ca060c56e3eff0fc6231",
+ "content": "a5a663b98dee63bef7735802f26b1cb723a9b71c521a979a27f6ebc7881e"
+ },
+ {
+ "address": "4733762e3d1c0781ab1f27c637b0105f2f59dd917cf6fc0ba4fb8d93fb1b336a",
+ "content": "886b6e64ee56ed8d892f1941dbb547de8f21f989f6c08a84b6f81a2690ba"
+ },
+ {
+ "address": "47f59b7df66ce9e8c52dc918069f0fb85c4ed462b397da89efd4cc50abcf88bd",
+ "content": "bbe557ae143898d3ebcfbf84a2731d33d53c11fb978f136c98f54fd11aa2"
+ },
+ {
+ "address": "47f68ebe96d6ad344c80bd4167f702d95cf9a44246e57de9408efa2d98fb9742",
+ "content": "785de4b93dcf707e7627cfbfe47dcb03dd7d8dae56a859b7b7e38550ece9"
+ },
+ {
+ "address": "485ba0bb7183d08dac2c0bbfb0e193ddea010f415b2705b8ce9822b5b4630725",
+ "content": "d540b19fa371303805e7232f9109811d0375648971ab401547b8eac337a9"
+ },
+ {
+ "address": "48b60c9998a076164069acab8a7e075bd1e8231951ebd89bb4657c11d52e75b1",
+ "content": "060fe1c51379a4dc7b962d21a27c07a7a7f7d8f47f69f8b15260dddcb229"
+ },
+ {
+ "address": "4929732fbca861d18a0a468ca61255e7be9653d11df77d9b1a1a2330ff34bd95",
+ "content": "a19a83e2e6a40eca5bc7013e624c2b0ac6599a8ced4038d9f27be00d0b51"
+ },
+ {
+ "address": "492f89931470e61f042839dc0c0b6560f1e174a9aeeba4396ecef094614a1e67",
+ "content": "683e192a0c902601b3565751f7f2c6d311676739734fae41c0d13ff1408c"
+ },
+ {
+ "address": "4946ec7460669035ff76a419cc4f0883a7e0d712584befe4981a635d522f7e61",
+ "content": "8eab33510db1753cc3105748335df301aff59ab0913334c873edec478698"
+ },
+ {
+ "address": "49db633ed2018295576e96e9431a4714e30e50ba8af4864f5bca928a60a84b1a",
+ "content": "175166873182d76524b54cdc450de25b6d1247b9f325dbcc777ea4bd8d75"
+ },
+ {
+ "address": "49fa50f7b164f7d6f18725d98d46735c5760eda8eb7d95ba623939be74c47603",
+ "content": "57c3a1aa25e8c1d60315534704ae78a70d897d9bfd266a1143c6b3bad6d5"
+ },
+ {
+ "address": "4a36059b249b2594598ae1d064038fc890504f6e6070dad2e6e0cd25dc253e8f",
+ "content": "7b9839cb3e0a66ab7d2332a7b05c9209e2eed4135f2bf1f0fc0983200197"
+ },
+ {
+ "address": "4b28e2d8fcad3da6a2c6f2c8ae9e7d2f29c60cd13ce0386bd2b8d46be0dc3eba",
+ "content": "7408fafb1162dbe4fa8860b593f0e599b68db7eec244c3e4651d3ca94d67"
+ },
+ {
+ "address": "4b337c0aacc1c226e3131731e8ee328847f25f408ebdcd78af6e2e371bb20aec",
+ "content": "7e7df9bbe265754831493662437a8d66bc44ce96cc381bd5fc7d159a552e"
+ },
+ {
+ "address": "4b3f34e7eea287c24f755bf22ae2000a37a56f3873c714b9e6bf1924d064394f",
+ "content": "a0b3d3663dc6bbc0c434ba7b9ce664367e1c915a8f105e994842a91487f4"
+ },
+ {
+ "address": "4b81cc6ed30b714843b42fa03e91e4087a059bbc2d85475845baa73400371fb6",
+ "content": "cb1c8691de7ce6b14ac090d3a579e0e3b1237bf5bb762e5579e508838ba6"
+ },
+ {
+ "address": "4b90d8f96f1a452387160e2411587ae9f5d38bd16146da9b4db39f58c2be3ccc",
+ "content": "e8a305646af97b818f9261b15b1cd1b840238278720f0119f64a31dc9cdd"
+ },
+ {
+ "address": "4bb41bf31a7aaa20e347d9cd374d41d0966c5115d54c3d635f923739b193717c",
+ "content": "e0614dfb0466453147144ae302b93c92eae8a68b67b42c37a309f9e1b9d1"
+ },
+ {
+ "address": "4bf9338039b8af9622b7252c19ce4268691855868392153f072460a0937d8374",
+ "content": "13787a2cb05190970e4a1863f03f852e14e4d88bbafd4c6bc948b82e8c2e"
+ },
+ {
+ "address": "4d025d715f76494aa6696064a1c03bbda29decf10b9759419ade01649232f4ee",
+ "content": "0ae706d98eda17fcd2e9fdb2fba9f6dff0b421dd5765e67f70fa013c6bae"
+ },
+ {
+ "address": "4d1c8a9377b57daabfe047cc9a1f8bf0cc48a0b7d8ecebdbcf6ca1a6c5c959e3",
+ "content": "e9bbb13ee485fb8f173ed06d50f49586327fac45007bd10ced43e39dbd3c"
+ },
+ {
+ "address": "4d43c324828871d49437fc9c27f1ac815341f555ae7d87fb06f0aa28b7945960",
+ "content": "750d994f94219f0bb85c9209c1bb3c3ed317ea04a4fb9a125c8a061de114"
+ },
+ {
+ "address": "4d4e2cb94597310c1a719256c79e471d083e51869a9a2168790d97631d716d75",
+ "content": "ff41f28349207b8e186ae7bca80e52407ead4f14f083658123d86550ff4f"
+ },
+ {
+ "address": "4d5003b19206c0be8241018e12537e1febbb9b7069b02d2e597c8c0de5222754",
+ "content": "e0ebc9c9164e92758960bbfdc6f5c9adbe5e17ca8a96c5e26f4501774f84"
+ },
+ {
+ "address": "4d7e52a17ffd295dc41126c3da7d68979b606c419f9ae8c735114442623a99d8",
+ "content": "d5129e189cc7ae5075bc98170ef3e7683eeda0a806b5cf96558527b785f2"
+ },
+ {
+ "address": "4d954ac166843d27257399049c487b00f4b810a07243658c815fdcb5a2b90335",
+ "content": "519a423f89c66d82d2c84b3602d7ec3a1d0f8ed89d43038ec091fb5597c5"
+ },
+ {
+ "address": "4da1e51f6d5c90172c3a77422d30b4eb6ca86eea4c936291462c8cb8e39d0aea",
+ "content": "411d5544be830f06649e52a71d9dca2949b4750348ab09e0f6d03e2726a1"
+ },
+ {
+ "address": "4dd0cafed7cf8eb16a55add5774d53e124385e6eda5541cbbb8388bd19079b6a",
+ "content": "fbdc34c0237ed19c4bbce5043405fd9a3dc6dc0356c6b420fdbd0e3f4d8d"
+ },
+ {
+ "address": "4e01e165e79cae676f302631c3795d79a49f24d2481190857ee48e881e62ec10",
+ "content": "05f9b42548e7d9ab46c941c2fd8e30d84fe68db12230dcb6434f9a7c6ec1"
+ },
+ {
+ "address": "4e3991b823a0aa679ef705605208c37530d578e4aa5ab9c9ad0f39bd9c559252",
+ "content": "4ff9b44e94af5d9f2348d00ea9f0c5a83f900f5592726a10881da483000b"
+ },
+ {
+ "address": "4e4bd0d2f52744b705a1bef1ba40b79096885fb641c4ffdf97dd0352eb443836",
+ "content": "8ca583ee3a3e13639b16c4d238f76a37587ad4baee828ad93a4e7527e2f3"
+ },
+ {
+ "address": "4ea6f530051a873ed0a7063ae6537ba0523451b996a70b3eabb45c37ac94717e",
+ "content": "c85e2b30a2b482bf3b7c3f17ce593115f75c7c540f9b24a70be16429d3bc"
+ },
+ {
+ "address": "4f3b116c99589586aae8790e173507d6fa7b39f8aa811d509548c75728beec1b",
+ "content": "8788e18f1fc9626b9d787ba8056c21c6311d8aca0e184f6e6dd2c2b47d50"
+ },
+ {
+ "address": "4f5d864816c14f0fde0d68c472253a7c6da9426d7e0b974585d512fa28c3a868",
+ "content": "8d4c32117002896102e2534e6fd9e74ca55ae79a7c5310e1084d4cf0a3b3"
+ },
+ {
+ "address": "4f79e5a7e7c381e23933c9300bdb789d7d1a6531e918599af74429400219b1a4",
+ "content": "3aa8442820b313cf81d1de1e8be5c6b9826c8bc443bb972a161c3a9ca8ea"
+ },
+ {
+ "address": "4fa949c7595e89a46498e5bcfaac11daa4b643f26214c9b9f769184bff5aad7a",
+ "content": "6a085bc9edba70e58bedae8d476c8c2c0c7a50f6ea8236448a6efc89f34e"
+ },
+ {
+ "address": "5018b5ada47eaaa80ef96688f6bdabd0c592a6eeaf3554e764fb9acc0066ac6e",
+ "content": "91911b0937527881486db6699cd4299f869e00400857f9ede7d8006f7898"
+ },
+ {
+ "address": "5027453d06c129399456d6280c42d1d6ae7565e322d1408d678b5199015c4cad",
+ "content": "9425d1a461dbb0dc526902f02f09443ae1fd6f20a424d42520f84ddd2dcd"
+ },
+ {
+ "address": "5052bdb0ca4e4ce4a73ac01fb0faac33ef981cc19f4bbeb78c62ea93f442beb5",
+ "content": "49cd568a5e6e1f94c67a0eca0cbe93a2ba3ab9b539f8b6a82f5be963282f"
+ },
+ {
+ "address": "51b61bec43ff08cdd2dc955e5a339ad704512607f19e965e10718ccfd95db13d",
+ "content": "0853d095a24f6dc780fcfb6a55d064d5483d0c78358b073f68606947774a"
+ },
+ {
+ "address": "51c89efc204edfdbca9596a2003660dbebe27bfb3122c63a757719bab66ddf60",
+ "content": "1bc01af747651bcb44f5c66677f21c965a08526a0cb513eb98d88f4cac3d"
+ },
+ {
+ "address": "5223e35ae7a2a6dfade6f5640c2394a69020627b44d34e1bd28e304ffc8bb456",
+ "content": "9a7792a4def743de1712b0baccbd8368f731a48a0dab016009d6bceb524c"
+ },
+ {
+ "address": "5280c20fee60c0cd7af39938cb7b743699397c0159abcb1596c6059289e914bb",
+ "content": "895019bbe138f20e4d2ce8a8ac43b0e5d1c237b029ba75d936b8c5cd8da5"
+ },
+ {
+ "address": "52e100e51b6a418cd2e532182ee9043d5d8bb8d43e57adf023011a68c4f92c7c",
+ "content": "63236ab52558fdaee744234ef7c168e8e84603ef73ca9a202d06c42644f6"
+ },
+ {
+ "address": "52e76de5118a081835c6bc2d3c31b30dd59922358fe52fbd77147875553c1479",
+ "content": "63e8f9c8d93991f9f3c8f01922a10bd8d1e6f91a4cbd9d2cbcae53ee314b"
+ },
+ {
+ "address": "538c7c42b8c432f2032d654c18a7e03e989224158d103e3a119c1ac94e22b955",
+ "content": "fc76c52e1df9d9e6fec380fee83a587b9c1e9ba641572dcd48335eaad89a"
+ },
+ {
+ "address": "53b95e5d7cfe5b6e5587e86bbd02440db13c66c380da6b43380e5f0abc3f3c41",
+ "content": "bbacc129ad89a177243b8d33604f2b31de038b055af0b065744caaf852f2"
+ },
+ {
+ "address": "54087d4212ce763b2ad34e3b5582698270a361b4a943d0dbc1bc70ee4ff32233",
+ "content": "937fc74df92968720571190022cd9023dafd2154a344ead40ae492180e65"
+ },
+ {
+ "address": "54611d5b77cee4934e708f6cecd18706e7c5c298e0f4d0bfb292d6b53019028c",
+ "content": "2b9b3ede093c40996e9808212b3f6b5bda52c2e556709e0d3358d5ce187d"
+ },
+ {
+ "address": "552be8acf09473f6e00d1ca0a4bcbb6029d7280702d16874520277461de99d7b",
+ "content": "09620149688f96c117ea4a005ad38b87e02170eae0337ec7ed1e2a910b10"
+ },
+ {
+ "address": "55591099948815ea3d13acc060e28b691fcc016575c19aa9910d981226e5e9b2",
+ "content": "673e1b4876fd33d4182afe9bed4075ad8995b623cd85e7b728550db0be64"
+ },
+ {
+ "address": "5561b79221962bd81d14b849a34f964eb1a67f9c36ed415eb42896a053ba5a45",
+ "content": "d23ce76234318359cb41bd75ca26911d7491bc461f231cf507290ca8492e"
+ },
+ {
+ "address": "55a4d4c45bb6a38bb9f0275e548115248602f58f185141d6681aa80704c16453",
+ "content": "cad4368a82b0b11b083f79c5e8775800e8779f1be9e8f12a18a75bc564de"
+ },
+ {
+ "address": "56f83c7b1ec7e3041e19fd0ace067e62643d905286bea1fa30fd01799d3cf8e8",
+ "content": "f919596cca2f34fb3ee7b976708030db9944664d1e6cfc841c49868933b3"
+ },
+ {
+ "address": "570cebb1d94c81c615392abe12aaada36929b41e3a6921cb51989b9c90374355",
+ "content": "ae13e215293d551382f65d37a828ed196f86a98500be5846abb242228b44"
+ },
+ {
+ "address": "5748bd5946f89223e1593dcb20ca48c4923849a710b35c085120f4362d3a1a9c",
+ "content": "ed8ee37b22aae7e2faf8ff5a66a2a6b52faddc1f1ec15e03b4ec85ed516a"
+ },
+ {
+ "address": "574d482d236f421eefbdb6e8ab5870df8971c98a3e8437b7cba5e52e87c4888d",
+ "content": "9d83adade2e7599921455a7e079098bfd43d4b2f0b9bf57fa859574ff19e"
+ },
+ {
+ "address": "57857869b6eae6ad5173e1d3e19fd73e1f7575bebec5ea08d42596d6ed6561b1",
+ "content": "6225188b83a3bcf72e6ec03a39f66f3cd6ec6f5e2c583b1ba55f695bd476"
+ },
+ {
+ "address": "5790ba1eb3a358698bdb3adc88a4f48a180acfec16155ec3710c0c47d3555ae4",
+ "content": "e17eaf628ad2573d69e447a2bcb0d84f91d844a52f44ff02d9101b208244"
+ },
+ {
+ "address": "57d3d7dd01a395f25e94b6fc7f3facc843cecc730b46bc716d0df0520fb9ccfd",
+ "content": "d9225237ef9954d6712748cf79eacfab5d67d74a97ee1828206fbeb46100"
+ },
+ {
+ "address": "57e71c9e1d2cb2a8417e138e07542e2f5f0535d1a7ad5d1e1808b230c32d3874",
+ "content": "270c6e43fb355ef1bee4d6e5d9e7242a74b4597b748a3a666eac797d7c62"
+ },
+ {
+ "address": "589cb0b014677faa5e53da04fa47dd3abcf2ccab28d59ca832c5c5938b0157bc",
+ "content": "301bd688b3e0be6e9aed866a2a2fc5bbc71c6c2425cff9609231cb37eda9"
+ },
+ {
+ "address": "58c6cddaa89104163e4641303a062855c6a1507c4e9b2ddec096d1d060a49462",
+ "content": "bf6f490690a1abf8177f738376a8689ae77e1cd8c98791d77b43c69e03bd"
+ },
+ {
+ "address": "58cfad4e9d1ca12759b7e3a85f3a72aa25d7b0deb11db05787463458567bc1d5",
+ "content": "fa2feebcfba23583c725c49eff09de009a3524f6d3adf88d23117763f596"
+ },
+ {
+ "address": "58cfd4832340e34acd472164283d4ab830136036b523c565285d6c9189e06bec",
+ "content": "16243dab200065ad0e5f1fea40cb269b7b7b658b36aefed1acbd58415a39"
+ },
+ {
+ "address": "592e770d549574fb67200c4a133edd58ce20112eb0a0e312c93874124485f4b6",
+ "content": "93460b04679dfbc16a05ee701d5468c46c719b74aae75a45b3db92ff7c5d"
+ },
+ {
+ "address": "5951daf0a54f06328ce27a0c56fe1beaeed127b55c4503f9add7fa314de7aa7b",
+ "content": "bd5ff2746b73feb9672e4c59f4fe3990e265d0e81674803b830a24e75ee3"
+ },
+ {
+ "address": "59ddd37e9c737324a320687632f456d632e847118a914f1a921cdf504150f5d9",
+ "content": "d1475f70e283fb0ec4e7848614bf5be2530ba5bd4313ddb0928171acb73e"
+ },
+ {
+ "address": "5a17b70d42b9a64cced0ec56d23191143a71a4772086cf7e735e67e4df8af200",
+ "content": "398de8b370fd6c85c901e54430e529823cb4d2c00d4abc09385a245f94d2"
+ },
+ {
+ "address": "5a1e0d0ff16377a2e708c040f0198c1cab93c6bff366ccc098575b5a509dc588",
+ "content": "ecb48872235166533a795e0a9633a9787044678ba6f6a844695c8d1af447"
+ },
+ {
+ "address": "5a97e29bfbd841cae9a8de4e26c6e2d35f03083195f63d44aa93d1595f1fc942",
+ "content": "bdc18d7bca5f9b41f91d7fbae35c8f935aea4ac1e9badd5369e649ed899f"
+ },
+ {
+ "address": "5aae7b4b76635fc343a30e2d7dd849226db2ff71fc7e3f8d70b3211b82b78723",
+ "content": "acf77d0c18dfff040d7008e41c477c1ddbb3e41b15e9aa99e6041f674e08"
+ },
+ {
+ "address": "5abba303b815a1160c4cb7eac7f437a33be67c8c91ff0e0f0436769cef1ee58a",
+ "content": "b6e4431632aabfc208d4dda125dc7399a2ba9f73ef7c134d5cbbb8fb01a5"
+ },
+ {
+ "address": "5ad2d638b8bc1e44842f7a6d18e7cca88f5fc2899fe6026af8b0590b0ca8a0ff",
+ "content": "8532c1379a8811138017f344187375b606c9da1f8f8474213063868d1437"
+ },
+ {
+ "address": "5af98422b5b3014e194898daf5d354e89e05386f49695cb21d9c46b48bb22e57",
+ "content": "0670b43587112002f658ff96ea8906b4741f6e326a38d0312173e8feb9e5"
+ },
+ {
+ "address": "5afdbf42245bb9d42a2bcae78ee84399738ed023828430528e0765be76992191",
+ "content": "d106139d9442cbf00e232897abecd330c5e69b48d9091a9b0de16fe76534"
+ },
+ {
+ "address": "5b21a4565dbbd1f9ae12e0083252b38b79d240d738922f53457eae9646c7c38c",
+ "content": "fc6e983a760292b8d0c2bd5d6f37a9c425b8db599cfc634bfc8736da1803"
+ },
+ {
+ "address": "5b99a3ab99211a0906b78f8f3dd10f8bb148e915772a2d34cbcf50ee78ddaad7",
+ "content": "631241290d5d451b1ab07924c9fd020ff94db8f65ad15e4e0ad33b2efb4f"
+ },
+ {
+ "address": "5bf0de38f0da9556a1128ac008867201ce537a6e9f7d7918777a4937257732a5",
+ "content": "5168fc746b706adaad2e41708defb51f49cda76013da889ab8799a5ee619"
+ },
+ {
+ "address": "5c168851a29083b530b4acd163eb864762fcc0f49569dbef15ae98e6cef5f06b",
+ "content": "db702cd7ba14e7239b2de09e0a201a1b250d69e9a372f349b19df327eb99"
+ },
+ {
+ "address": "5cca4cda9fce0f063c4e6cda9e3804b7660f7bf5e5b2cc2e603adf9fd82a90b2",
+ "content": "dfa0633b161afcd2bb97c3c1374555690c68781382d9c5fdb74e41ae8d4d"
+ },
+ {
+ "address": "5ceed22a4804732d63934c8860f528155ef5842cc99e5e8c903ddda242c50f72",
+ "content": "def8b97e9b13f14f7c69d301eb4a852b39fe824ed2e9242b148b2047d52c"
+ },
+ {
+ "address": "5d4afc3fafd6f2b3e26d514f36f9bb9b9f58d70081d153c07756f1549195a2e6",
+ "content": "3a1c41922e21fe221b1e9f80397c63e2c19f2807e3030eb01a12d883dfd8"
+ },
+ {
+ "address": "5d5a21296c15c0d6b3ff1755ae0b112b35a5860398d35e14836f062f076bd3cc",
+ "content": "49bd490b1f9f6512de2fb6a913ac1b06e69b4ed5bfba775ad84c809fdb74"
+ },
+ {
+ "address": "5ded77d1054a6d1846ce5e359db7c2e294adf432fb50414ba90e43a047bab05e",
+ "content": "ba78b6b4f9e96e68b9f3e9733f9daf4b59dfc1abe38f4600a258203fce4d"
+ },
+ {
+ "address": "5df376d285e564a7597e2be000f1e7a637bcef9373afc40cef0761dfffcd3972",
+ "content": "f29e97b0e316117d83dfdbabe258252c8796090a2b06213b459216b250fe"
+ },
+ {
+ "address": "5e33fa6a580cc41ed67d84aed4bb5e3cf881715bfa9f2a2a836f84a13c3cf8d7",
+ "content": "69177582423c908d1f6e8caa4a7309d92fad2cd5c0d31ab85ab51a033b8d"
+ },
+ {
+ "address": "5e90f1b6d7029d6c6dbcb0c20bd0431e739848151e8b924ec20c8cf3ae039a5a",
+ "content": "514af13f5b78f09dc3da5249ee341365ad64fa34f4c05477c0be05e2823c"
+ },
+ {
+ "address": "5eab3fc19c9976e5cb8263470c4fa0160a8b318d056eaac8c2c229444ed13fca",
+ "content": "aef5a00f770105ac4a97d2c369c059e6690de61b635b7d92dcc40ad40db9"
+ },
+ {
+ "address": "5ed9c17f43a86c10166fd547fcf3404ae956a864f22ca12e83767bd03fc39532",
+ "content": "4ef0abb3fc92464b82c22fb1f9bd785916e646076cfe362b0ed6d5a720a1"
+ },
+ {
+ "address": "5f0576e800f9712599af0a01b47ab72e3412ed0f2f24e17306a5d755c40f0697",
+ "content": "fcc0049c89056a0fc2ff33ab43f0183b82f4ffcae28e22ca29e9bc21f502"
+ },
+ {
+ "address": "5f2e225723216132dd6f179abe141e11c4544e1111286555828717f50a62ad69",
+ "content": "b0244edc85a91b53b10b7fb4dd1a55c6d888763f56dfc8b221eae9e980c9"
+ },
+ {
+ "address": "5f7141dc92ef0de09e88fd82c37d6aa9b4de198e838815e280080d69120ac9ab",
+ "content": "ed58b99035e7e12202c6cf01208b90fb10d153c957bb9041ec773abf96d6"
+ },
+ {
+ "address": "5f736b7c2b47a5aed3fc20bd2c55114c9cf2764a22ae692204854d18d17b58bb",
+ "content": "ad2a7dc5bea2b8a6c6cd2775fa217f7cc2bce01b2c41d92c6ef0cd365c28"
+ },
+ {
+ "address": "5f87276416adbedf22e5c1ab95048a6e854b68c71ef9989ec8334e5c8ee2108c",
+ "content": "cf88a4eeadd8858c5c456e927af05d76ef7dfbf855b138875972b857ae29"
+ },
+ {
+ "address": "6030f519027d233a99c28d386e9440d58b00ee7779f004ca7aa475b66ec72b44",
+ "content": "aef4a945b7f9d97717e944de21f21251dfac92e93345a303a187e8edfd6c"
+ },
+ {
+ "address": "608b8f09d9eb6dfa7e6caaf11a400f5a105cd1cf7324294f5579a4c98d0a1121",
+ "content": "b35775567e1b9d64402e38505f657330d65362791ddec664e0de81dd2662"
+ },
+ {
+ "address": "60e0ca92e1a381f0e701c4ec2a032e630b41161a17f3a50f9249bad69d65d5a0",
+ "content": "5b9ce1c138e3be5615d87b190497c7b6e70df85c0f0b62f9fb01cd0c261c"
+ },
+ {
+ "address": "61942cc45f98881cb660d6d89a24c45ae54d040bd494c511e303c684eb9817bc",
+ "content": "a2a8d523a5c3f3134730cd2b61f7f82fac3b4cdd1e43995ec9750873656b"
+ },
+ {
+ "address": "61baee3a134c91c2e2b1cd2b43c02f545b6e148157d20d9651afb0d3f10eb866",
+ "content": "381e128e04eec2f32b02fe659f01d42db309ced0410092c485963901ab31"
+ },
+ {
+ "address": "61ea98291eeddb3cf80df2ebb3264410fb880da2b9df9d5191bcc5d8e87ce341",
+ "content": "f757510065553a303a1662686e2d3e075bf61f8f64dc8cee2b691054e418"
+ },
+ {
+ "address": "6215e8038d9aed9186597d056ce4b1c2c8b05b342dc14835ecc8fd2d1a115caf",
+ "content": "133f6ad5c3e289ba1bd45d0293349d626bb89305fc24cb65da9954988a6e"
+ },
+ {
+ "address": "6228328f7d80a290c77df27bc823253a1875ea26d1443ba7afdbdf36f4d686c2",
+ "content": "ea6d979e592ea5d356178652a5bb19bd85ac4b0864238a008e3479faa9ce"
+ },
+ {
+ "address": "62571bd801bfc6ba67c8d435197ed814f9109f9d2e50a81a9e042b52c542fcd9",
+ "content": "9823ba811cfb5c52001a02a244aa5fae6e3b446a02dcdf25d0d86301387d"
+ },
+ {
+ "address": "62a011677c63656ae04178aa2fdfdd6196cc2eb468ba922afb9e57df898a9456",
+ "content": "094402abef90317dabec82dc2de1f24bf2e61b04f91af262fc52d2eb505d"
+ },
+ {
+ "address": "62df062820e41df5f9a071cfced60f680dcd931f6ae83d5ddecf4bfb39b9417d",
+ "content": "97be25c9f67d52b11f990e55f477d53122b1aca8ad522afacaa8b5855cea"
+ },
+ {
+ "address": "62e55d40e9f01d97dd428ac7cea2fe6decb59e261892d471953c07ced7831c89",
+ "content": "2d519fc6ecbffb6550e51a210972bfc446cff7bcabc7477bf0b5b453c1cd"
+ },
+ {
+ "address": "62ef2d162d8181d31c848af945707e51733da412ae06e37509c398dfb0761f0a",
+ "content": "8e538c87f3cb59c882bb8dad10ed6f70fbde6ace0c595560fecd8e490380"
+ },
+ {
+ "address": "6388cf0796280bad2f042ee83f2c7064382e58d8731629ceaef80af03a2194a3",
+ "content": "35d42555733617fca20a58d146055dff9dd8ec488e4e3ff5dc1386722601"
+ },
+ {
+ "address": "642a17114538bd2b8d1e46bf183475c9b39207c250740a05e139ebed9ec061b0",
+ "content": "bcaa869acde00040016539e5e9f6708f778a01a32a3785d723ead2d81a64"
+ },
+ {
+ "address": "64603714e35b882085b3d1e03244f3387a8c8a2fec29a4809035c8ea1c98d353",
+ "content": "a117203363b990fe9d8be6f8ccfef70572b2a90840756ce52dd5f36e7d86"
+ },
+ {
+ "address": "646982e3e87714532ade5579aaf13c1806c614a9b8a53673aa6047eb68c117f6",
+ "content": "33551e750dc2e8870819400c865b15ba76ea1bf9fa10f45d620f9aaabd39"
+ },
+ {
+ "address": "6483759aadba0655a06d75c942c5e477b3a6f6f5d65410399b98c5521aab3a30",
+ "content": "fd5393816343bf830c0fd4f67c2e4ce123842a03d69807ed1602e7143205"
+ },
+ {
+ "address": "649eef7d5a99f107a27370464cb1f29622de9d9b314502c2b1ec0acb3ccb9d2d",
+ "content": "d35dcfa27831623d475e9016a0d0c101c89d714da97c64c493038fd9d6f1"
+ },
+ {
+ "address": "64f00ddaeba5a13cfebda2048a87c865adb5fa6662a8412add5beaaaab7c41cf",
+ "content": "14a90b377af323bcc835f6f5f00309ccc251be9cf9054b6ce27c0e2f75d9"
+ },
+ {
+ "address": "65f0d40e45e886592e9d34fc47d6a06e75250bfc7569ff7ab9d237a2b86fc553",
+ "content": "29986d745fe55722154ed82a3c638309aebe558a4681a456f84d3a8d1c90"
+ },
+ {
+ "address": "66e5cecbe94b04a1ca7e553fe4756e7bc634a98fd7aef0b33cfc8f791f9e5a88",
+ "content": "e1be9df1c588df99bf7dd1654429a032041676990fdc6076def08cce7af0"
+ },
+ {
+ "address": "66e99ae07554353f30e4dd9941e3ceae0e7a2deb90c88e6a11f8a1627f9a5000",
+ "content": "c7c903ff88514e1e16fb17c6f0900e152e6c43524184e3dda61e4831dca5"
+ },
+ {
+ "address": "6709300019492d15fbe8673c6431f825a414da44921dcb215b3608c352bbec59",
+ "content": "54ee66df2c56525f9277265316499c0227581f52a20ab4d6fe78a96b87df"
+ },
+ {
+ "address": "67103d59c7530e603d09a422f15797c432aa5713e3c75fa5cced27dbe087d704",
+ "content": "3359afbeab7de03125851262f5f986bc6d0a8f8b00191b10fd20f5c42034"
+ },
+ {
+ "address": "6726da8526eab8412ef1a1b81ec900118940ba06238112796ce5796baca064ce",
+ "content": "5d9c66268a987d24dda19408b02c825d74ac4e4bce3de4dbf61af980f8ba"
+ },
+ {
+ "address": "672f0d1d4d1c96f305343b3f2626ddced54b937d567487f5235f62765677e8da",
+ "content": "ad75e69a2138e52a3437ac58cf85ac61cc4b12782b50c801d947e6c7a614"
+ },
+ {
+ "address": "683a5f3d5ed4df2e5958dcab1045b884515b33f5b852d963760b71ef97cec180",
+ "content": "ca5fef81fc70a30a046988641c77e89dd930b33901a0fe9c4d37b869339d"
+ },
+ {
+ "address": "6843f97516eda5906e710cf1e67fa42d8b3726aa5173a96966a8a2deddd405dd",
+ "content": "a4a226d613c17196d7579cae08c3edd88dd463211e1a8577cbc1ea5677ea"
+ },
+ {
+ "address": "687f77b861c62bf7a1eae9f50d8068236d670a25dc51c2309b76b4ad2e551ea3",
+ "content": "d58ff1cd4b47a0a1ded2521fa9123016d4545ef0f8ddeb086390aabb9e81"
+ },
+ {
+ "address": "68ca3536952e9985ea60b4c45ed93ed8aa5fa9b1032607b8542f0fe3e5d49621",
+ "content": "a326a3b5383bbb33623032407f330c3e75a99df5874abe20e000f55f1964"
+ },
+ {
+ "address": "68d0a7202ccc4983678abf6f6a0356a92815982a35fd4c2d77af905fd4979827",
+ "content": "4febd268faea14d73b657957600cfafe4deef4434a8fb2f60eaef997d685"
+ },
+ {
+ "address": "6917eb79e0a63872b7297ac33623d4f58f9c475fcb0b3fe7ccefed7fa0f40cd4",
+ "content": "8219d363c8d641155380b5b3e8140b29fbc9c9b0e63d47fe644a7cd5bd65"
+ },
+ {
+ "address": "69468f9a5540afb9529eaa1ed1a70239b8178b26ca53992aaa6b730e5cebaaa8",
+ "content": "baccc21dbe5b85e3b83ada3e2fe052d289ecc2ec05673b3703396dce30cf"
+ },
+ {
+ "address": "69aa7d0960e2a162881173ece7d3845e27c08d77eb41cbf62224f3ab2170eb0d",
+ "content": "759e794b9dd47eca8b01f780cce2c1f40d94c21390ced7f35b954da151a2"
+ },
+ {
+ "address": "69b11172b49f98251be7de892f37641bf11588d12c735fa1a4f27043f229b0a2",
+ "content": "2c95c0504f47811ece0b64cd1e1c5edf0122e494546c626fdcb1e6ca8842"
+ },
+ {
+ "address": "69d7b9407e4e5a31fbf75af2553b2199311a0cfffe30d31071e5643ae63795be",
+ "content": "aee4ad55312ec646cf144ba091f414a1ab23a47435fd8bedad53343e43df"
+ },
+ {
+ "address": "69d823ac8e01b83560808d3a7b9785a98dc3d563666a5cabc7e751e233251172",
+ "content": "3aa75a66f2176d882e30860a6596680a8b3b6a33af59a2edf7928e3c9f9b"
+ },
+ {
+ "address": "6a78acc508b14b62c1f212d954a2ffde52500904c585dba2ddb385d310d1b658",
+ "content": "403ccec020aac5b7937658092e65563634d5f35cbc04e42928232428ffd1"
+ },
+ {
+ "address": "6a7d7062897d40f33f6f5d83aad4bda583b60fe15ea111a37ea193bb112c1bf9",
+ "content": "8bfb0701e6995cf87d30e728ad3caaaed47620429859b01f72bd19af19d9"
+ },
+ {
+ "address": "6ae53b7b17b56a859cc63915745fdd1e258e81235fdb53616d20e983ecf607cd",
+ "content": "637ffb8ed85bc73b4cf3bced0fe43606fced70d7fe57089682003af89ac9"
+ },
+ {
+ "address": "6b070c88ac4da16699353c5284e9d8404db45e2738af4abb50dc4f213884c01a",
+ "content": "c82a132789e655d36df31fca99fe450faf59e8d72f753d351b0559f41b55"
+ },
+ {
+ "address": "6b08b572a4f0b682edbb62193eab6f3832ace19157a0009453df4c795ce5eeeb",
+ "content": "e3754721a11667333644822131afbbc69e05f9cd142e2181215e79b1769b"
+ },
+ {
+ "address": "6b0add71bf90302c2c623e8b8d4377b387d2148db940e24f17a2d1a708f11720",
+ "content": "00b0de859506797f85b8216f718099a7db3bb9889ea8f9408e8064891c"
+ },
+ {
+ "address": "6b35c1398d0b51ffb27bcb85b4b9b16cffab3b27f2ade28c76e13d3eda5f7af3",
+ "content": "fa62e9668b8300a669f7661f7bd194ebe06d7e3089c09bc2844fc5b7e679"
+ },
+ {
+ "address": "6bc58bcf08aa9c780c7265777366d6f19a7cff8bcb81878e95437931e1e9a951",
+ "content": "d5c71cfdd97e7e862d528ad140dcd6cf0d3ca2deda3967f68c26ae44d5ef"
+ },
+ {
+ "address": "6bc65d87d3e8acfd32b323515d970b5e47158704dc39b1d5804d1030fbe84243",
+ "content": "c43832bbbf4e2eb23527a5b610b92e02e0427e2e1f997f6e5d81d9bca0b9"
+ },
+ {
+ "address": "6be71d23275b6fc6d5c7892e7f2c8ce0da7ad47ff2af0d89a09435cb32394ac3",
+ "content": "65e6eff5506ac3b7038e59c797dbcacf262ec4ef54a0320e12fdb9b28533"
+ },
+ {
+ "address": "6c03a2c9ff0e089b6e76aab7fc9ddf578a4d09b5d965351f9c61a2c06f437feb",
+ "content": "262bb43af43738f3c487810aa0383866b3738422fa99e3043d59d88e1580"
+ },
+ {
+ "address": "6c2ab34f575c6b1a7871be6aa89a0d548767fea85420b0892ed3b50b8e1fa7af",
+ "content": "b1b1043aa26054f8e3ba2bbc969e490eeefb9767798c3f9dce022d64930d"
+ },
+ {
+ "address": "6c7cc44a173d8b8679142d5f1a11873d7a4cf701fe45344ef476541ce861e8fe",
+ "content": "7e147d46355a7d5d6a3e6daa92020dd733ed3eef65a8c29532de307bb171"
+ },
+ {
+ "address": "6c8a206f00fec21323c856347f8644e4b5c4839eeb3e60ac65b0216173c6e527",
+ "content": "0514b85c9b61daf12dd55ed565f6e2e2ba6a07bab2e12f7df8f8c197eee3"
+ },
+ {
+ "address": "6ca1ca2db69d3569e2d0409d64d90304805ec0c0187b7e4dc192407ac4dbc8f9",
+ "content": "9978e5ba92b24fc8424d42820d11969fb6502ff161e55e04743f9a1b4255"
+ },
+ {
+ "address": "6cbd9148eb179175078e3c516e5ddcd3c61beb81c038eeab338f6e3d5eff43ca",
+ "content": "97fd3cc1912ea9117f1487c340d1f3e1296b7745fdf8bf246a437d861642"
+ },
+ {
+ "address": "6ccac522ffe71fa315b8979ecf663918dd9f5717b85866d4ce9f04843e4ab820",
+ "content": "45fa8c4c2b953c2878239e29497d86ed02ffd9ebb5923add829012a72070"
+ },
+ {
+ "address": "6d131f879e403c91a1d5c4d30e4914d24213a7c0e95ffdaa8f5eb825b1301e8d",
+ "content": "b75b40488499c4bb7963ca6c0b2e2ad373959d7c70cfb29175d905a44f22"
+ },
+ {
+ "address": "6d43a4fb3d280b28806511a42ce704b2c26e9363d07d660555dc0dc0bf613693",
+ "content": "bc003ff477ed528c444c59740f7fe28836e6365d5d5e6259050b0caad1dd"
+ },
+ {
+ "address": "6d8cfda7735ec255c55f776ed6d347aab76b1e03a9eb04996281140a3eb04308",
+ "content": "2a3ff7c6aa01014dbb10630933a5e6080bf826520bd34b6934b881fda98e"
+ },
+ {
+ "address": "6e0e11c968f8700716571fecc2c936b115fe255349262e453dc68dfc89d51455",
+ "content": "120c6ef3afdcbdf6e41a620092d8eaafd03d0f534cfe875ffa5fa4f4e24c"
+ },
+ {
+ "address": "6ea9a094d65fe267247bf8a18d8486fb8f9ae060dfbdd41b9012f3b0bb3e2001",
+ "content": "19f060ae0b83ffd79c48d1e8c69ef5d8e9e2e2481a3534517364f710c5af"
+ },
+ {
+ "address": "6ece745ad6e0949b276516024c81412f3d3c77d0a7a9f0aab8b522e766cca155",
+ "content": "9dad797dcfad1d0aa0b73283972241a84b3b0428d7ae36f8c7fdae028473"
+ },
+ {
+ "address": "6eee1e3ad24e982c8f23f280b4186ef7f49614ffc8e8eb73e2b7f8d1fdc29906",
+ "content": "c545b5a1a4128a30787fc2b0c7c425afc4cbe7ab9da5aa49052f543d64e2"
+ },
+ {
+ "address": "6fae0aeac48fae1fc8cf881f89497103347e4b4d3dba7179fc72890225bd42b5",
+ "content": "91c06d7a3248da246e71f861f6dc8170caf006f829797d71b802f8984c66"
+ },
+ {
+ "address": "707f66130dd45f81b6c3c4b950814cb5830cb77b3000579779cd0843240e38b2",
+ "content": "a1e69602b1e75b1f7b895305b5f8d889804471d88fd554448f22d0232df2"
+ },
+ {
+ "address": "70b81222a944088a8d780ea5baf7cbf3a571dfec7c22f434fd4e1966057b8824",
+ "content": "7ffca34cd0df480362694234f89e8812d506a5bcec045d73b0d1e6ae3597"
+ },
+ {
+ "address": "71a814aa52628a8d9801bb7328815416a066f657091e88cdf3499c2288bc9aed",
+ "content": "ca85f41e458d3beb9ee45711ceddda07d261bfe580c43cdf912f8047f405"
+ },
+ {
+ "address": "71d369a35e1dc8aaee3dd9169b5f43b388827fde933f81330b7d2be797de3c07",
+ "content": "196b0a16673248ea4a30572f854c5e362457813bee3ad269532dc99f5039"
+ },
+ {
+ "address": "71d7a5e1d2d5e6b0120c35eaa992208ba0fc2d0c1986d9470f6103e2da6682ea",
+ "content": "6560c880df322b45fbee3877656aaee842bfca136933c03ce4258b4e1edb"
+ },
+ {
+ "address": "7230654f429a8536d6be9c05a56b87447fc417837ed8602a5c0c09a0cac28451",
+ "content": "f8f56e75b876bdc93e5c092acb0852b3d57c6f2b5041ef24b9cc56fc91ec"
+ },
+ {
+ "address": "727fab711635cd89ac69ef5e9af21f910e2a1c528b96e11b2f4cdc9722891e36",
+ "content": "927417250eb74d58f87e47eff6ba82b9bdb4248c14617074a0e160156914"
+ },
+ {
+ "address": "72e5560cd1216afa4bb28be8a0804e5fc745ddc80754b8f48e8efb7bf86eaadd",
+ "content": "c41bf45c807ce7864e06ceb67c1cf5e1460045fd34b1afa4f0068017ef2e"
+ },
+ {
+ "address": "738b9832d7fd8e13179c40b44b8b4ee531a0b6428897d0490dc5a210c4868625",
+ "content": "d9bee35178209bbff9cd52fbcca621d2e6caa4a1350b95fc121090619b4c"
+ },
+ {
+ "address": "739330c11ff1beb4f09fe50e4d2f54ac0e30e7d61785408aa720e3504a0a824f",
+ "content": "9d9b10ac488ce69f651660594cad04c5e9b807060e83009b9d5d71316400"
+ },
+ {
+ "address": "740cc8e58397faa8040d2af17c0f685feb38d9926f0e99f78f568f91ea4053c8",
+ "content": "6490f8759239f1bfa8c0e98583978a0e44e8cdb51fbdf7f28c6bb30a28bd"
+ },
+ {
+ "address": "7448dd6ab667fbe50116e7b5c5fda5e4e0fed7da50bf189a92f7abcf1f156b9a",
+ "content": "6e8c1f39b26d83190452c182884961b911edceff5c238a7efc53fc689353"
+ },
+ {
+ "address": "748b83faed1026fc0d491a7802e055705278c65bbaec1a7d467dd5d192934dd6",
+ "content": "ba6d7fd8d2f8e2bf09cd2f62e50a1b153cfefa27dd5cf2aafa2a9a57c72c"
+ },
+ {
+ "address": "7494e8681a42fb67490d80a13c3b56876bd44fa8f3318c31aa026d3a5a2e4c42",
+ "content": "860e9a4f5164df302b0e29b3e8fb2beaa6922078f7fd02b34a08b5f208d4"
+ },
+ {
+ "address": "7542f0ca47f26da87641f97007e9169da1004b334c1560355079f4a7d19fe822",
+ "content": "0472844a4522260c431735b6be44adf6e1351bf903b51be007443aac36f1"
+ },
+ {
+ "address": "7588b28661db6578b78cdcef8765dc0ae58b8844356532ebb21ed82ae1a4e9bb",
+ "content": "ea231ffb6e6007669ff0765c8ccb730a82a27b6079b6bec0492568f9a16e"
+ },
+ {
+ "address": "75d3e3bf08a19d84f5f8ed47a09b39b4b1b8e54e40a6d04a6307f970ef820c78",
+ "content": "90b39038d39a1ec863080b07129527b141ca15fc9c98f9d75be909c021ff"
+ },
+ {
+ "address": "75d4084409136f213b7344998552ecfc0d5a43af88881b8a5b4383af92881916",
+ "content": "6be71722744ae75aeeccbac7f69f8fc783cccddf7cfe7ac287c1079e33c3"
+ },
+ {
+ "address": "76062e7c849e562d919ed130cf090fb2084d565566176a34b04ef555d1e07e4a",
+ "content": "aa29197981bc44a8ae41d840a4ea298c2b6fbcb79764e1bae53dc2b557d3"
+ },
+ {
+ "address": "766dcbd448b803e8f263facadbd873366a4eacf26750f2b6ad90caea551ba8f4",
+ "content": "bea7222efa6deceb767486a1e24af2491d48d181f78bdafafe21f4b68bf2"
+ },
+ {
+ "address": "76a39696cb58147dc6547a06a91bd2ca209c63cf1f58abbea30ea4b3761b5de3",
+ "content": "c875d566d21e65c1d8c7f8d7fa383f7c85f2b86e5ed218493a30954c187c"
+ },
+ {
+ "address": "76ab1d7ff685e1a587e9c728c76595d85d278413d32f83583b3a3317265056b3",
+ "content": "8206234651d66af13387aee693bf33d313a035c3dd7979089981b89ddf98"
+ },
+ {
+ "address": "76fd01b9d5975a2a83068e2a46b2d2bf659a5caf867a9dadedc5a10f87924e10",
+ "content": "9a995f4a3f06114689d6677e5e9aa088055e15e2b0aac072206cf5387e06"
+ },
+ {
+ "address": "7775388ae9318908633cc53518ca477be1d991347e71a3eb3304ac59aa53f766",
+ "content": "f9cec8ab78392e78228805e0d850390dfdef85b1b98339a4f0c00da95e3b"
+ },
+ {
+ "address": "7782b68d00455874bc2781bc817428d579cd9d8822b6deba9b9e94e516c61842",
+ "content": "0b8dc2b6345d189d15ccd9bcbaef25cf9917daabc3790963d64ae10a60ff"
+ },
+ {
+ "address": "778edf71062bbfcd45b1b394923ca48dcd44cb47449764d7a644ab94db1d313a",
+ "content": "381fdae38b6ed7e1ff01365da42cf8b4bb2894cf0ec59a9460377b034c88"
+ },
+ {
+ "address": "77c1083a7e21f45ad7893971a0e785bfa1a17a6688b364ec2c41a26d9f28e8cc",
+ "content": "480a9c4eb27ee823cbc7992369bc9442a199ccc826ee4fb895d017aca5e4"
+ },
+ {
+ "address": "77d35676eb71f106f2cf1e61ba0c23eef5503a32b164ac792905786665ce88f9",
+ "content": "7cf4113fca8badcb9bd07e9742924c78b6584b614743b64af5a1863096d0"
+ },
+ {
+ "address": "7844e2d1cceb255002b7220f97fb039656ec45060146098eb1389860b83556e4",
+ "content": "ca7a38838796ad6868f33ac3f5356f6c9f1287e629cf33b6c41477d62ad3"
+ },
+ {
+ "address": "78d9f54331d73f637f3778b7429d9d4b04cb2e694a9d52d31e0540a03920f0b7",
+ "content": "d5c17c4dff0731fc0777d6652b814acb11907151a1652b16d86cb5c86d39"
+ },
+ {
+ "address": "79388c2450946a7bf4bead6aba4a8d96192d6a69577f85956e3ae86193030d2c",
+ "content": "d0845015a68e6865f682545e645e1e35ff3d4baa0c40ceea6bf9436e03ce"
+ },
+ {
+ "address": "79c66e14221a5b8000e3f4bb52f76e33c7040b80d88ee57e9a7dd120f09a4437",
+ "content": "47f1baed9e3a3d363bba1da857a4ad1112b1f9722901a0615187b7da5a89"
+ },
+ {
+ "address": "7aefbd93f50e8031117542f6100784ab993376b026c431f944b678c7403e37f6",
+ "content": "cb5d7ca31cacf52327fb864dc702cc76199b3df1f15ccdf22942c811e5ae"
+ },
+ {
+ "address": "7b1b54f0d3210535637c61d3dd62ae8119ae7ce600a5f94db6a2b1baa6437d39",
+ "content": "65c94051cc3acf82cd81d51a26ae11a33fc69fd29fb9f1b326b141f567d9"
+ },
+ {
+ "address": "7b4775d5fd1029a8cc16914bfddb1e2e1d35cfd92db8359f0ae65618de55823f",
+ "content": "06a978a80856de6c54f196f996eb3f4446162e17db7d6771b845e3cb82cd"
+ },
+ {
+ "address": "7b4facb643c28c67b632a5cf51bfcb54ca451b618ac100a04aeb018cf30bd781",
+ "content": "af672dcd4766d13c0d60a2ad9af845aeed4b20364f92675cc0d5242d1d5b"
+ },
+ {
+ "address": "7bbb7145b4c225532cddbd2a1527597caa30933dde2f185244bb6d68aba5f1ed",
+ "content": "3336103e94ea7836ca615fe87ccf7a21b58df417049e13dd799a116faa1a"
+ },
+ {
+ "address": "7bd1e180bb2d8c36081240595619b96d160d98a9da4898dfb6e36f4be063f2b5",
+ "content": "fd8c29bc180555574ead3fcc6f312dc5142734d9d21f7e66abc17c20ebb1"
+ },
+ {
+ "address": "7be113006ba5bd462c8aa418fa4035f7b3fcfc5812b47d38ff1a22e674bfaaa0",
+ "content": "aee472d328ce54339f2bb045c038d8a45d76259d3a73b5397bf93873044c"
+ },
+ {
+ "address": "7c20b9143cfa26ea28b20718007236f4d223029e0131c0b41bcdd99eb7c7fc4a",
+ "content": "2fdf7dc520458855f4d9fd0f7a1666754f952dd0d868802b18259c6fc245"
+ },
+ {
+ "address": "7c29d3dcd7e0ae178d32f36f9ffba386d11a8e33b7fa19874b5a33b5e955d898",
+ "content": "072814734cd1e89772af4d5ba3331723f2b133a24e85fe5aa4e036e04d24"
+ },
+ {
+ "address": "7c523f03a6aabdea3f77a3e29dccd5c1928185f274bb3724e61118264e06beca",
+ "content": "d0ecc101fca3c6651b4bfd340d3416264bd872d2e9c33707200966452dec"
+ },
+ {
+ "address": "7cc0e55f0f5c99e8e04a40d8becab35d23c31f7bac00593fe6cca572a84d0076",
+ "content": "41684ee6d416988001b9b59ef47ac05bb324ccb7f328aecdc415e197381c"
+ },
+ {
+ "address": "7d8b8a3e687de47d3cc5b1f9a4072ce0cb6a95063b1924808c08c98dff101f35",
+ "content": "2970eed1b0b8b20f6bb5248f0bec0a4bd219dcdd16b200041b03fbb3bca4"
+ },
+ {
+ "address": "7dfb35158c71796d8fe96ff6f2c7a73999de11b89ff673671552e256f55b07be",
+ "content": "f1f7ace32c9a4286842dae4715f72f4eb86eae1af03d53a82328bcf08d0d"
+ },
+ {
+ "address": "7e56954cf2e81c1d568380161f0770b4971006db7cee06bbd65abad72ecea03b",
+ "content": "7a08c8c5eea51b3edeef179a949244351e112abc6a2d5df3daee7259b508"
+ },
+ {
+ "address": "7eb0aacf51da3d5da03989bc31412ba0fe28aee31f88b61bbbd2566567ffa538",
+ "content": "e67dc0e663ad82a45f7ef77f049a0a3b88430f37cb72343bbbb3d2867b8e"
+ },
+ {
+ "address": "7ebab8408feb9d1c7432cfb851ec993a739db277f113a0e2df659dfaaee0579a",
+ "content": "92838ebec1d892551bad7e9b9b3faf3a3ba44b2fcb5c42d361b76f214a77"
+ },
+ {
+ "address": "7f0d223aa875a92a861cc28d1938efefa0af00dcdaabaf883eeff83fe2d6a0ad",
+ "content": "091bdb2aece5ccb5a2ea7b89a2c584197e38bf3391e32a657dfb45e1cd7e"
+ },
+ {
+ "address": "7f17860bed98f44604c4c5605c86b874e3544e23590ffa86030a76b7a025479c",
+ "content": "e2fdac7456e8f559dc9508f349b454decc7efdf720e7aa9e32c2606d984a"
+ },
+ {
+ "address": "7f1deeed3e115379142191314e376bc98a9b9cd95d45838b2e7fe1d263efbd14",
+ "content": "b44509ee43dad6e5ee3ed376fb23a803190932e1e7c274e99a2f39142d7d"
+ },
+ {
+ "address": "7f3d760e33eca306998d486846bc821e5d32611e773729efa286edb8a3134834",
+ "content": "24837aa0adc97420c4b5a7c4170d918dad264219319d3941a98a7dada494"
+ },
+ {
+ "address": "7f536eb03907a1b66d1417d7d5567971cd862bc5f08cefbdd1e72557d257dbc2",
+ "content": "37a37c705cc54ee6bcac28be9fdea0ae4be28725b93b013c9a6f41856387"
+ },
+ {
+ "address": "7f9b7833f7aa773ef45564c09f895ff1892117156ee18207798c458e60e96409",
+ "content": "36733f50a3d5bfdf55a33153cfb985937b815f27ac9540283c3a811246ad"
+ },
+ {
+ "address": "7ff5dac290c229c77439292a78f68355d7401a5241f6fb63fa6ab4c88c77c8d4",
+ "content": "530ccf5bb90ecefc29207007f2c17e4afa192ebfffb0990bfd36006158c4"
+ },
+ {
+ "address": "7ff75ffb8e4e8f4a5d7299b6624345cc3da3dba0c031813bb03aee4aca94dec7",
+ "content": "4a8dd9c18ed3895e3d096bf3f63fec14b8807d806218e8ac7e4a18768439"
+ },
+ {
+ "address": "80043ccefbca8c780a70cc08df7ad4c07397670c1a6a3645cb2ca3b4da44840c",
+ "content": "719bf6295dcb82787407084cae53085378e3c39078378870116cb5b2fa66"
+ },
+ {
+ "address": "80439f0ecfb54c498644a5d2305f5f1c28b71437d2ef0e1018bdae2332b2bf68",
+ "content": "4a4c45ad93f0a4b648df05e3d4779144205b4736f80c2de8c8fa71e47f1a"
+ },
+ {
+ "address": "806d7b2a1bbbe42bc79d5989ab5bcf3a46bf19e2b6fac98adaeaf2ba4a7f933c",
+ "content": "25002744ea4a5622ee243e72dba5d2f9ddcaa2a47b2e7dd067e6a95dd609"
+ },
+ {
+ "address": "80b9c0e269522a39fabc311106b6514fd69298ec1e74383da96ea7fc47ce6bbc",
+ "content": "fd0948fc55c394a3b4164e5db3481da6d894ffa646106f197e5aea40b29c"
+ },
+ {
+ "address": "80e1d2a28af04ced2b8b137eb250271c6dadb7153b2cfd610cf1ff361ee12890",
+ "content": "dedf3e3482cedc04d7a6465790bf6d71d3fd1d5c406ee2b1810e4c21f2d1"
+ },
+ {
+ "address": "80e884fc0cef96b4c80ebe27d5643b46e24e25a075efd39311489cb1e0d6101b",
+ "content": "0dcacc584d2a605b7cb8fd9c46f04e5f75a554ed6735b1fa00a212f95b18"
+ },
+ {
+ "address": "80ef44cb40344ace4d640d51a92b845338c8281c7acc9d5cf415b4683e69cd0d",
+ "content": "45d6cd83f1a2be0ab456efc3d6ab54fa937bfa2d53129be86dd3a7a58654"
+ },
+ {
+ "address": "811f97b958422b23d980fa82f7c2a15a88a0702fe512f94f45ff6ca2db451dd7",
+ "content": "204eccbc36d1c41005cc70d51363c1cdbefa1d5a09efa83e35738c40bab0"
+ },
+ {
+ "address": "81e2e86c71b010bd41c3e6c1e2c69188eda404fde5f15a741f5853029d189c7a",
+ "content": "8451cc9694904794d093bc4223b0d018597f1a1c4cf4f3c25878876c186d"
+ },
+ {
+ "address": "82c1d2f7332361109deb3258a39ce54bc10c53f5ce803efda589bc590353e4c8",
+ "content": "43cbb164caf8cbcb15ee343924e3334ad3ed96806628563e32e283921047"
+ },
+ {
+ "address": "839c2abc6df2c68186abdfdbec3a72200642902306878cc513057dbf650cd155",
+ "content": "1ddcfd118c21bca75dccd7d808b0aec94500aa3613306e17d700e5f91205"
+ },
+ {
+ "address": "843d7f3eebf9213e7a21661cc592f26151db7b8da27a750a8684d2430e639394",
+ "content": "03dd830e0d95276ba6ba82b46c042945d88dd7c3e3f353a1c23500d58e04"
+ },
+ {
+ "address": "84655980e14e61dcecfe42e07462963d4b5391c46b642350e51dcf922154f772",
+ "content": "b1652d91660d23dbb9e2bcd0b62d2b8090cc9cc9af6cbf94b81691deb98a"
+ },
+ {
+ "address": "858395411889c7ad68d1ab33d4b65a0f933fb02a7d2294d6a1e7685d9705d309",
+ "content": "1a46bd77c7949f46eb502595a12735143fdb85449f53b83b89b837b910f9"
+ },
+ {
+ "address": "858ceb3d4e162711197f829d172e6e3f4c5890cb52a8bb009507d16e2ab3144b",
+ "content": "9eca7c18aadb07dba3dc4befaa6aa3380ef954bf9db2549b97ea9ceda8c2"
+ },
+ {
+ "address": "8613dc68b661c2486d6913eccfcbf2c0675f11d2da30cfb684b0da494e89855e",
+ "content": "685e8d800f2f8a4e2a6ef8a7054170ee37e2954fbe2756eb7ddf01b4417c"
+ },
+ {
+ "address": "86154efb7df14e95818404c0239f2a41059f7a0c8e5e60b5f46d1f48f64567b9",
+ "content": "126dc3083acefcf79c8ed76afc3e4f4ffb5d83b337dbd6ca36f9e23b7b3e"
+ },
+ {
+ "address": "865697b9de9c177d3eedc7438e89aa2f34b038d754ef7354d51c2128f8bfd81c",
+ "content": "96aa7b472cdb24163bb5f550c664687c54829f44a8db02b6eb3e4954a2cb"
+ },
+ {
+ "address": "865d7a6638cd37d3422040019378abe7e88c950b30d7df5e2b917d4de18650fd",
+ "content": "e4ebf6d10c30f44290040311f6e55fcbcb404e8503c8cf9bc00673311cc0"
+ },
+ {
+ "address": "866933e848c1db3970e855e7acfa1fcafdccc3a70a91f0b80f8e95fa13c83f3c",
+ "content": "488b6581d9530f3985677cef619340c12826cced0ed349eac8476e8e4586"
+ },
+ {
+ "address": "86b379771e6229181afb3aa59ac7b527b00016dbb50ebdbcf9e85f843208c26b",
+ "content": "02a0272803b06babdf24f92b8a881ea39f3375f2a9fddb34c2e14046989a"
+ },
+ {
+ "address": "86bc2cf0cad420b26bbf3b194081f56127e2c5b64708dbf5859376ee567d2144",
+ "content": "a5e4324ead9d7e21119045c43ee2ce6e72aa368c16f02c5f0747b2fe6d3f"
+ },
+ {
+ "address": "87b9d3ad66b081d157740901c6af7f985d6836b0f96c5b01605a2a261c6a78ec",
+ "content": "099528392ed207ba71e68faa95c416de02c22eb7e6127fcabc8c30c314d2"
+ },
+ {
+ "address": "87da85c4716cd65ef2cfec4fc7c770302e4a413ee41a87c7ea902e981ee3f6d9",
+ "content": "e5792c6b967e2f25e64cbc85a2bc9a1376d7028c35beb59efa21d297be85"
+ },
+ {
+ "address": "882f0c4a1433528542a5d302d2d93fe214d5cf7802830bcc1c687de4e151b26b",
+ "content": "c4d28b4e43447824813d98ad0e898284471f8a94dadd714d6e6740416add"
+ },
+ {
+ "address": "884792afe996334fedf20b63a641f00914605b3d0af23970de3112f85184002f",
+ "content": "cdd4e9e2526c3662155f5b59d162e54697e29d88c9691982ed509176aba9"
+ },
+ {
+ "address": "886fffdd39bcdee196081da7f750768120c4e22077001cfe15e7e1b90b2f41d1",
+ "content": "4aa3b122e55911c7ebb268740c7771cc004e4be6da2f2467f3516b88c4ef"
+ },
+ {
+ "address": "88b0377355083e824fdf8545c89190c6f86e0cbc960f53256425d1013e634046",
+ "content": "53e2c97e8d91fd1527ef1a7de17bae731ffd13e751f50b5f453d0427bfba"
+ },
+ {
+ "address": "88c8498d55c60b9bb5a6a13102c59e8aace62cbf54ef65cadae3199c7e7133d3",
+ "content": "75e2866a12bf20be6e1e8bb0f2701031a114f02a987f88bcbc42c7c112d4"
+ },
+ {
+ "address": "88d476c084884fb2e31611e4fbd456e795a4e222f5ab234cddf58976f7ef64cb",
+ "content": "df824b7e8a27eacf347ee1004e2355f8fe4c6e5a5fd363f9fd9d616dd033"
+ },
+ {
+ "address": "88db59cdd20ac84d365a5108bd2924ba6d9504f7a0d0f569772c4a74b94c3d84",
+ "content": "798e56b40b60f4e16bee5431913b9fc299911e36b775a307995cdce6b9ad"
+ },
+ {
+ "address": "88f2dc4a93c7dc63895b68dda58f254e2597550a4dfe46fcc5b841e0b41ac22e",
+ "content": "e0ec63af5950d5ec039b108720fb358daf4152f9a4bfb6e519136aaef323"
+ },
+ {
+ "address": "890adf000c75c2408f1e3cc07bde8c709a3440fec3c8a267ea9b43aaff0eba82",
+ "content": "13a50e7bf09799717f988d819eac87adfb264ad8fa889829dd205f9d5fc4"
+ },
+ {
+ "address": "896922188aab113a6d916683f02d7e4377c4802f5c9a0b9872564014f0a9d521",
+ "content": "2d7ac3cc697a168bc014316396abb2fac9cc68c927a700e316f080f07d50"
+ },
+ {
+ "address": "8971ce20a65901867190a7be49e49075e83de5a15d86ee4c8cc96cb7a6937af6",
+ "content": "2bd37b63c14acad6632ebbca18ca290b50ae6aa20f4b65f5318bc444c610"
+ },
+ {
+ "address": "89e250fe2f5e707b3672b0cb0cbe972ef7cf5dc553168c301faa8e287cfff88f",
+ "content": "6b86ab990b467f0997dd5f26cdfb4f029d984969d71de29db93744a1de08"
+ },
+ {
+ "address": "89e4a0d12bd70fd92aa7f07362d8bf8822fe768ac3604c3c1ac7cfe169abd2a5",
+ "content": "91b5835adf2060f3ed416b4801ad32fe7c63c0c23b714d514ce95f532759"
+ },
+ {
+ "address": "8a17fd5c9a55ce777baa489b2ccd62c8926e72fcfed5b78ea58cdb32bb229e03",
+ "content": "5072c5fe1c612adecd65e0528cb38a826d81dafe4900a8bf72321c341314"
+ },
+ {
+ "address": "8a379a0bbf3e6a0a062a013159bb95b50936a16e4b8ef5db1f99777603fcdedf",
+ "content": "539b8588400769c50d31b36214fb49f70d6e2baff79d81091da35f180218"
+ },
+ {
+ "address": "8a59c278bd869b747a427bb2ac8d9a39bb73706ece9628df3fa10cb0d80ca2c3",
+ "content": "ef8f4f6bfcad6cbf2aa1caf03f5fd248b517cccac1c8e9405180f9c836a4"
+ },
+ {
+ "address": "8ac06741fd4a9fe1f3c885c0a387e142d7b14c629dca7bcd6e4e9b2ca3729126",
+ "content": "37f0d270f3d8b9c95e6c0520ed9c713a5b417e4cfc02e4c465aba31c3e73"
+ },
+ {
+ "address": "8b0299009474ec49463078019d59df057625ef55ec05772d58c55f9628d61de6",
+ "content": "233c009b9467be53073ef86c4c7d7047f676bd9a6cacefab1ec418bbe1cf"
+ },
+ {
+ "address": "8b0487789332810a243f6c27a6a46eafcb15e7bd83eed2db35d7d631382276e2",
+ "content": "38cc9f96179edf3a6742b10540648718b41be509e2ba39d094f59c67d94d"
+ },
+ {
+ "address": "8bbba83ab051c3eba57f31e6945c97fc893774944a11d4e1802357ad3f7f1857",
+ "content": "e19b44e297ccaa89a8ff34607f1dfc031e9b141956b07b66f968e2fa4849"
+ },
+ {
+ "address": "8bca35ba511afc0d807a7f5b3d054a5e16316ed40cc676fcf5c61d7283de3a90",
+ "content": "dc148b1b078473c5518809b8cb312e6c30cf6211a040d39204813a8f2c4f"
+ },
+ {
+ "address": "8bf64fbbe948d0a8997b587bb0af8b419cd74e5cea32983f3cc544c2348e6a0d",
+ "content": "163d7b1b2cdc4d2e400a31b38233ec3a1a4185d0aa4cedce26788a45ac7f"
+ },
+ {
+ "address": "8bf6675451036ead99a9e540fd64939c03d393d877ba93ed4618009501f004b4",
+ "content": "f354448fab04376ffb3cec14b11e54a4e834b43d7193bcc115b209feff06"
+ },
+ {
+ "address": "8c489e0737a1a19e5f0e3f829d48521566a75eccd652ebd35d0b4193aa9919dc",
+ "content": "b817bc2f8829028aa46f8a28e1cb65f1ddf2b9c3fe07ff9cea30fc961b01"
+ },
+ {
+ "address": "8c56c759b20542daea57ac21a9e1cdc8ab2ab998f061ddac081ded921c2a0d54",
+ "content": "ed25b62f05c844ae4f587e0d04985bb07e05fc7428166e57e5fc924f9d78"
+ },
+ {
+ "address": "8c8fb134cab0d402ba8da2ec7a74b6bba4c220581c2fe99fc2de1dc77e9373ac",
+ "content": "ee4ed99578ffb7fe4726f1db58f26efdd0325d6b5639e8913af62b2788b8"
+ },
+ {
+ "address": "8ca35708635fec0a6328866f3d93992f2979bc505eefc80221c57ad3556a5199",
+ "content": "e12f2ccbbc3fc14b4f9631ed1ad5afcdaf46c2a3ad5e9214c468dc0a4f3d"
+ },
+ {
+ "address": "8ca81b3781e341b5828c277817d4f9081cf043937a3188153a64af9212ff89c3",
+ "content": "50e830df87d9ca43a63b15ed851be5af31367756e6c0d391edc8a6394510"
+ },
+ {
+ "address": "8cc021e5ade0bff06ca1cebabe9c98737e2f0547fdbd3a6da67884f397404e6b",
+ "content": "8b2b336634d972dbb65991fc27e87655587f0012e93fff5aff17d3a6cc8b"
+ },
+ {
+ "address": "8d964b2a16678eaba662071dd0a1ce476a1b3350abfe0c624fdde5ce75a08cea",
+ "content": "5e3c4f3188202313c4de9569c1734a8a55ba00be13dcd019fa7b1824bb74"
+ },
+ {
+ "address": "8e583a4564822d651be0c3eb3ff3d0bcdc20eeb671d3dd30073d5ad2fbcd3c3b",
+ "content": "b2aba459d35ee56aec19a38f4379f1be1cd987757070711313daf650136f"
+ },
+ {
+ "address": "8e9b3d689c5f917e08b6cfbe733c2436a5eb18f2f332ae0ee84f2110baa748e9",
+ "content": "c80f6b979cc6fc3fd1f924b1b81facef20c17bc2083b2356dfd5174e590e"
+ },
+ {
+ "address": "8eeb3d3860c51499c494458a32445802e6556ce72b9074ebaeb56d608dca19c4",
+ "content": "d91940d10fa641957ca0fe3bee50f5705258a75183f1dba52e957c9b0fde"
+ },
+ {
+ "address": "8eec16b5680eca196d1b34a7851aa73b840534d5245739099adf81c0c313447e",
+ "content": "e03012fc62005cc4b515968120f491a9bba1ff6cc4067b492708d9b9f82f"
+ },
+ {
+ "address": "8f5dcead7f6e00f7f90af837483ecc395d2ca84b2fb530ceb2c9fcb2cf3913b2",
+ "content": "4b714e77b567991dc79ad8a5a1bc50bef2db58221984141906fc39fc8254"
+ },
+ {
+ "address": "8f71a29dfc31af3a4f2ed63bcbb522e894929104044619babbf0fa50f2cbaa98",
+ "content": "78ad9ba91ef1bf8cd3d2750c251ca8f6bc5f245115c23add0a4f2c13db52"
+ },
+ {
+ "address": "8fa28cdceb7307d796e510ea5c28b749694353d245f6cbc618198dc2f673eab5",
+ "content": "409033c22824b1e0f99f408eec2d257a938aa009a0a755c3feb3fdebbaa8"
+ },
+ {
+ "address": "8fc8521e24138209165097dfd7c91b36383d23b756628d81cfffe6de3696ef83",
+ "content": "c0c41ae6c09bf6aaa2fbf1f1da1aa45568b56d68df6b5fc8adca6bf74000"
+ },
+ {
+ "address": "903acd1569ff3ad5d852b04bdec8923c7febaabf1a7fab312c8ff4c14072ac53",
+ "content": "c90a5dd79b6b3a5c207d0c7f8e5145c72cf3a466f173f157bad105a2cea6"
+ },
+ {
+ "address": "9040dc4648b7cfa138349f4647840735d473072930a7c7bc8a9609b91771f0b8",
+ "content": "a46967d435ade7af2d6458679bf04ab153d4a208ef5e9e3a0bba7f3edf0b"
+ },
+ {
+ "address": "906af32c9965170a6c6b665c393f1e78148297ecd5b58451ea709b4b2830ac30",
+ "content": "f8569ee3c361fc540ec9dadfb5e0290faa55c91360a6c6791a922442ab55"
+ },
+ {
+ "address": "90763ef9aaee7ce68407c148bfea98302da13a3b2b56eab3d0ce34193213665a",
+ "content": "fe831b8c927bdaf580b809b6e65bb1e497fb7348be3b582707d3ea20e801"
+ },
+ {
+ "address": "907db29715da609af0fdccbf857dc0378968af2693ce654f070d786b12fcad6b",
+ "content": "f010e81850204eb973a3816df34a18880c46c97ce4979291ecec69ca8d05"
+ },
+ {
+ "address": "90942ab61442e01c1561f1de052971e427e451d23866a1306b535bfa673fff42",
+ "content": "df6f1209c887bb5a7eca31ef3f9bfa69cdc195d80c3483feb4b258fd5a91"
+ },
+ {
+ "address": "90ae06a8da86558741cd3ce63f6e864f1b01dc4d5e06f0f3c7585bb021abe2d7",
+ "content": "4f4f5164d1872bf58d93ec0e3332fd4dc44b60378f75e66f2bae05a761c5"
+ },
+ {
+ "address": "90beb30f57bb2bd3f8dc8633e4e9e3ac6d4cce3353b7b251b80fbe4595fc8cc1",
+ "content": "631442dfc3f96223ccf8d2394630d7efdab9020715c19ba0771399c638f1"
+ },
+ {
+ "address": "90d0f4c275580d00f589d77e5e46d6b6da4b5b50964e2a642c6a1d860e24a5c0",
+ "content": "98575a90b596ef8553381c33dad3a194bbf24a9574d8091fb1af75673bfb"
+ },
+ {
+ "address": "90f8ea80cd43a464dbbb6175159b17dc1dc275c53f883a816c797450b214a893",
+ "content": "25c04b3104716f20a19d9040a4897638f84d6734f8331a57bc10060e329b"
+ },
+ {
+ "address": "91337e1c5feeb0a5d87f9a1661063fbf4bd37ea6fe0345a0b1f3a2f24c06b887",
+ "content": "fd429736ecdbd8aec77ad1dfd6156bc6a83a4564e0abbff6be0bade5ebc0"
+ },
+ {
+ "address": "9141811ba7353a0b09a047373ec0dd207e299d1d778b5ee7d4b301f718c6a1d8",
+ "content": "722655129738607e6a67ae7416822c727dbf476d8f14fbeac1f943e878ad"
+ },
+ {
+ "address": "917f5b384739ce12fd3b3751b4ea5577592bca3457e043e65dc11702f3d65a92",
+ "content": "338db6575f66fd202c3b2fa2761944223883683b86abd4dc9b70564bad4c"
+ },
+ {
+ "address": "91dcc63a08b48ed7c65370090457269ac728cd64ab1c80053584e322876eee65",
+ "content": "c070ff26ff88e44fcccc7942f3c48d09e888dec1abb0243b7440fcaec773"
+ },
+ {
+ "address": "925cb56b68b8f59ed3988f510be6223d6cfe3b8a50ecdb3c7695af608b2d0a8d",
+ "content": "dce1761440c2b2bce161427517d2504ae4f2ff187b651623316a4575cff9"
+ },
+ {
+ "address": "9287c0d9d508be3221e204d39414701fea29601083bb9af5ee65ada5d952dd04",
+ "content": "c7c4812b42be5417f2e743d9807d30c3c3a2ce8ae4f39e902a2d26d605fb"
+ },
+ {
+ "address": "92a1432d2cd675892db4321399e145178f400035c273fe3df499c994a48d2963",
+ "content": "709385bb107e19c08b0cb5c6837cbb42cdac7c84072a5ff1de674bcb03bd"
+ },
+ {
+ "address": "92e819b29ae9ef192ea90fbf557da2a25f1673edd3eda866394ebd76b4f7e10b",
+ "content": "6a750c94659195a1d57ea7aa17d34d353d21235fd3195288031668e7a5bc"
+ },
+ {
+ "address": "92f16a4b622932ab0dec44ae49f569d8a3bef84e5c9e39a646234f05683d3ac9",
+ "content": "41df7b5d742042aaa78822d2f635da6d4bd7a6b9ec8d82c5148fa215e5b3"
+ },
+ {
+ "address": "92fbc90b6e431cc3b6ecf358b7f0f201a258c2becf31bf48a1db9bc6ec73a272",
+ "content": "3a80fac618c19d0cedd1b9a61d7c1542be046c250ee85adc2b4e5b7cb619"
+ },
+ {
+ "address": "930a7416865eeabdea12d91cc9aa98a48511c15eeb038bb87d2195e718fb0506",
+ "content": "ef916b75b3ba996b5698dd09025b04e2d6d2626a2c79ae748bc178d3c85f"
+ },
+ {
+ "address": "9335277b76a3f8796500eba636da5d3b8c134b38de9cc957b83e7d11d29c8b6c",
+ "content": "75b172b3a96bfd297cad7998032133dd1d0c2ccec5394eefc89432b6f4d5"
+ },
+ {
+ "address": "93c00a2293cf039d3284c4cd9c314fbaeeee2d23998f94e0cd19288919ed047e",
+ "content": "6268e08586db068294883e6d169453ca6bba0b25fb318af0355e8e0b18d8"
+ },
+ {
+ "address": "9564bf6da1a2f762ffd2c028db58b8d80e1266a720f9f5706f02a2b66467804c",
+ "content": "ba471387d5a0b78fac0e134d17d02596cbe9aa95342fe7120b9ce7e9a400"
+ },
+ {
+ "address": "9580f83b969bfb54329da6caaae95f10415af6c36ddbb24429d250b187dec8aa",
+ "content": "4c49d7777c9fc22ae80dd1d5bcca5c12a9d4c780388592a8614f8aa0240e"
+ },
+ {
+ "address": "95d0735c8eaf0e7db317e500e6dbd74168224d684f6a40e0a0a109d2996ad956",
+ "content": "4d57adbe59507595bdfbbb184c4a1891f1b057eade49c4f43960e1de9c57"
+ },
+ {
+ "address": "96627e650f1d92be92a973e43f0ee9bbb3424e5a09b567f45a4b753fff950057",
+ "content": "3088adbb2b89116f5c67c29ab35e5b2f8ce8611e851a4ef64cd29bb4fd26"
+ },
+ {
+ "address": "96961d2c1f448402d6b9acadec5950692ed6d286dbd2f12392d9553fbfec5c0a",
+ "content": "fe38a4f8453f8a6bf8b03f2eac8fba937d4da12f84e659703c5df0b1be1a"
+ },
+ {
+ "address": "96f3a2e7e96d32e3c30255dbb1a6eca2f52fe7faa92620358ace4602298ab7bc",
+ "content": "d4f81af24ffa380961e7cab0c0786652e740c912eea4164768ea8b35e3e8"
+ },
+ {
+ "address": "96f40d47412ebec97c461eac8a13bf754977b2928d798b8762e0052160db7b71",
+ "content": "34f93dd137cdc5767ed4970943cf6712f7d98aa87ce2e81a3e6d368b0b3f"
+ },
+ {
+ "address": "971a65cfdcd3638385d2f41d35133536773daa12adfbdcaaba1e272af93cd34b",
+ "content": "b3dddc59c0810e7c1efd8ae0bdb9b854119dd26d1781cbed06a66b2a0a05"
+ },
+ {
+ "address": "97471f60f88eeaa3f25b81e9034a0c72c7e391c6f5a44fcfa9c84001ce00bf42",
+ "content": "45996d8c562febc79a6b5f1b58ce814a1bec60ba69fc2ca5eaa19762f920"
+ },
+ {
+ "address": "975cfcdb6578a7955b0737b784404851c98a6ee8a2a31dc8a0d76d2c0a358b89",
+ "content": "d5e0e35061f39c75655b39f2b89ea635241c43f9d7ad36a37e02d517fdd5"
+ },
+ {
+ "address": "979314bf4a4dc6b7cf21c2b9f9b3e471382f50a1ee0fb5b28fc1c83c63280869",
+ "content": "9ede2a4a4fdc2b8ab4117450a89cca17251083bddc59d7a9b2a2a816520b"
+ },
+ {
+ "address": "97a573f8823993ddb9b95e5b0e22572729473aceecaccd156c126d6f67c1103b",
+ "content": "9d8589b33e32abecbe80ad5f90218fe3f31cc9198db2ae7d7212444ba591"
+ },
+ {
+ "address": "97aa9ac492817aad3ae4d472e6e592f49325fe9ce0c9f83f74b98c5677ebb475",
+ "content": "8b085e664a6b5d4de42cfafbe8bc9b1b77a1811a19307084692195267b5a"
+ },
+ {
+ "address": "982d3ed327343274760bc5dbdcb23985347c9cb061500e9295c2b450bff7eae2",
+ "content": "d379266c673131cf328562bd54b518f904444496770ec8b9b66c4cae9e09"
+ },
+ {
+ "address": "983168f6195a41d935f8c2273f815656da1444375f6f7866f2e1ad4f23055516",
+ "content": "6e291f936b458f321c52a140bf703e45f1607193c7e6e8d90dce69d97e84"
+ },
+ {
+ "address": "98e23a319c76ceffbd7682baf154be1ac69962d105db60ffb286ac6849392fe1",
+ "content": "b41ee7eb0e6ed5d7f35da8874d7db0d297e81a8df37159b149390daa15d1"
+ },
+ {
+ "address": "99100d420ae55456e0dca61f7093c07fd36f8a192c41a86c6d8f82fd5aadffb9",
+ "content": "acebb25ef4d5cbb0549e1d3aae927a91b75898f24e842b284e133899788d"
+ },
+ {
+ "address": "994c2cf792786c8e4c6f1562f4ac05a08914f61ad3ddef0c2a057fc62ff5a9c7",
+ "content": "89a16b63fb551645d62941c67392faa7cdad6e701f5b0639bf0fd9cf548c"
+ },
+ {
+ "address": "99ef8395e68c737d2c937e126d27d21d87cffe16d83b3153a50086359ff276f1",
+ "content": "7c639aae84366a4cbaff9b272da7e487807344af6a2763a5919f4e0425c4"
+ },
+ {
+ "address": "9a336c1bfd19471cbcdabe5cfd8410965da8d24806f20f0ae2c8aa1789bf16d2",
+ "content": "5f0821487771f5ccdc1fb14ac508b0b44933b1a747c71e23b726cdb5e06f"
+ },
+ {
+ "address": "9a4ea573f0e27a453c0437cd720714db1ba1aa818501920c38eb997e5913d058",
+ "content": "243b046b05a1ec16f4e41c17d57a104fb394890baa5cfe59f308dea17bf4"
+ },
+ {
+ "address": "9a7473ba854a79203786915d8599618498f0718c575c031790abbf00e625d94c",
+ "content": "875aa459a7718dc35a1b7f4d3e14a2214313c63f81c0131dd05834c0e698"
+ },
+ {
+ "address": "9a965e78693aba4ab57d8f3aa676812064c4343ce92247968c317237ad1f947c",
+ "content": "abe39888e07cb8c1bcd5e9ca4ec12c262bac3b0ae3b619c5c328258fc811"
+ },
+ {
+ "address": "9b2b9a04424c99c06b3b3a6492e659aa35a35e43f94dd0ac7138791a3b9cf044",
+ "content": "8556c2b2d22c66672742b38a54812d6d6c1ff573b6373cbf294383456731"
+ },
+ {
+ "address": "9b949f127966997cf9411ee9c54749dfb7c4a33e7a180bf16254453cffba9fdc",
+ "content": "d7b2fdc69e683b4fe8151252a8f4e0779c94bd50321d8a3d99c24b200c17"
+ },
+ {
+ "address": "9b94befa4c255a5dd5a67fc5842d86db001778296d41807f0e663a8c03818d8f",
+ "content": "e03b691985376910106a5ee7b6f6d243b672179840712afb37c671b557ea"
+ },
+ {
+ "address": "9bc61ade1df74632a8abc439a3579aa1407bd4b4637d439c05ce5b0c0fe4c4e1",
+ "content": "65f8828d61cb5de98baa767e6845c564a2e5252fe2b440e5abc2d3a42c4c"
+ },
+ {
+ "address": "9bd9bf236a219c8d938ee7fe7463473c8a5ecfb93860baf698ae9bfd78df4bf5",
+ "content": "f494e0d8e90cb4817095be3ff4d589bf48724d20accac57e263f870924a6"
+ },
+ {
+ "address": "9be217248e6d1acde716bdc26e41d9b2a6c43800614d067cf3f111e3ef904430",
+ "content": "66c04747f7ea72fab726bf7ca709ec89a450b7824b2017c1e9e61a0fb96e"
+ },
+ {
+ "address": "9bef98f2de07156fcb3bb5f873f8d50dc60c8270c830dfe04ae69c27628b0f4b",
+ "content": "bb399d21e7a58397607820a1c4305734317b86ac4729c6d1f1b10eff8c57"
+ },
+ {
+ "address": "9c29e115bca65705f071caa313e6936d2da6cef6a48b542178bf2d93ce260097",
+ "content": "d3c3f157381d8a96d9630f1072c1d7cb0d3eaf2df953bfa37474c5afb46c"
+ },
+ {
+ "address": "9c4fcf5f7725671309005c31543e64dff95ece39478a47b2b2375c6b1c22da89",
+ "content": "1fed75d7d36579479d052a095ed85aaa8af9836dda32ccd5da56fe382ca0"
+ },
+ {
+ "address": "9c6bf7ffe7ae877cb71700ae0b627e22aeec712d127b725f6e931bf9e7b04148",
+ "content": "745175a3d8d24152a8547de4672fa2c61d28ab32ea74608671533df7c7aa"
+ },
+ {
+ "address": "9c9b805ef65a4b2815c18d9fb53c248fb7c2638283d82f6d4c35a86e82f61785",
+ "content": "25ded02c7232204d6245e8b65ed5650eebdf432e840707dc0440f9038828"
+ },
+ {
+ "address": "9cce0ccda14ca96e33192153a295e75cc2a8ffef296dc668c2fa5faf15b7b364",
+ "content": "ed458ee681427734269896e6351eb2897bacbe165c63c38f758c828820c8"
+ },
+ {
+ "address": "9cf8eeb54a2f9e033240e926ce909e5154ce0e8212b9be6142e2e56dc0dadadc",
+ "content": "7c834f2ead2c9135821fb502e5b7e256883596b9c38bc9e59bf5d999ebaf"
+ },
+ {
+ "address": "9d50445b66c5bbeeec8f394f465997e77d08c05f1807c38e95073823cbcda59f",
+ "content": "d9d4229f2f678ddc73305758284691603705cf15fff22eb61fa27391854a"
+ },
+ {
+ "address": "9dbdb1f88aa347b09eb68679032e5d0b80b365b20b4951d6540ed2d0358b7cef",
+ "content": "3df646a2747e77d72f58d8cb267e680d93cee43f62ad5f08df01f0850970"
+ },
+ {
+ "address": "9ddb94c9c16c9a12cec155405c311b80fba876d966e52e9d21892921abd73018",
+ "content": "b112cb1ffd5b72e1b1d180f06e0f0b5e46815697fb1714f7965df2b39667"
+ },
+ {
+ "address": "9de1abde5729c9381e6573bcc91c88364d181a40bc916cd708452eab52fc63c8",
+ "content": "df63f000d7624442960e341ba2199bf6fa6df9de66502d621d8e3a23d0dc"
+ },
+ {
+ "address": "9e4c9ab0b892c23fbedc495033e5495979a4ab66e0df29fd5886616dbc9d2810",
+ "content": "eea36efb9529f5b4c428b27c6a5d572fe0d26e598a4dda67d9ed8fc3a82f"
+ },
+ {
+ "address": "9e95fe3530f2b59742eb8e52863d13180654db90f2f6a265228c3e062340e076",
+ "content": "5a546d140a5716c90243f1f9faf8b89bbd71af6fb9ebb490e2625b44ee0e"
+ },
+ {
+ "address": "9ebba37f898bee8aa96719b878b4063b40213c53dae5df88fcddf06daac28090",
+ "content": "dfc1644858622223291f1c584b586d0249e812ea6819a1e4ab2fd51445b2"
+ },
+ {
+ "address": "9ec04517e6f48ce3620a1a73390d2c80e81ae919d6a69bf45c147d2e6a8fcde9",
+ "content": "d69c22fbba69f41fe6fc4424dc0ae6d4ce77981bd7cb8b241b35ecbaf1b7"
+ },
+ {
+ "address": "9ef2ba24a170655454b108b4f0363d931bc8d149fc756183eaf58da35ce5faac",
+ "content": "8844d5ec62b8963e67153709b96cd65483f002b625e6888112318b2b2159"
+ },
+ {
+ "address": "9f2be1f78e1a717afecd4f9c1df32a41dff331bdfc7f23bde4f2a0713b769f8f",
+ "content": "1fce4d126691f9d323afaa459989300ce2c3a4ef576dc7d8d822de247e13"
+ },
+ {
+ "address": "9f9cb27b884a800e9c7186b71af4a8a3812e3412dd1b5dac725b1ffd9496704b",
+ "content": "7faa23679e085d8bd6e04d84594d0c2c0e59ff2ed5f21be53907da10ae6d"
+ },
+ {
+ "address": "9ffc015b5fd0eee286fcb296fa80433614aa64fbcda07e6ee0b900ffdaffd0d4",
+ "content": "2e8a096e7512e76ae648b9294d5af19fb4ce6349815012694f9333dedd79"
+ },
+ {
+ "address": "a10e4a32f93a95e35c5df14457ba7d3aeb6d3acf66091cc7edc9ee29d8098b5d",
+ "content": "8c65c1142f905334efb8e71495389c4edb29e71876c1c8d9acd0abf91f51"
+ },
+ {
+ "address": "a1ba57162fa414531578a796b91e84e437a549f289c99ebc1e8490985a781f32",
+ "content": "cbd670f12593ec7da9e50fbfe12bfe75e87a7822ba02ff16c1e95cf5350e"
+ },
+ {
+ "address": "a1d57a505ad0ae897eafd2101e033f500045e4905a5e3e463c4aa8646bddecdd",
+ "content": "9ef8b2b7fa143fc88bea021144c9eae066f55934b916ba9c51007e246c4e"
+ },
+ {
+ "address": "a1ee387c3747f003928642b6dcef37fcb5c89871de7fdd84ebfc6f6dd88dce11",
+ "content": "f1532f2e43fbc0a37ac04ce7976416cf32c177b3bdcac0b38a969b4d7826ead31f3c9afbd1bd45151e1d069559a5fdbd79a677106a8cb6132a6c07786f8ed83b54a1cabc103a012957898daa69f6d3e42167f1f9337cb3edf78444c61a258d24a3dbba9c6bc5839f471cb1fe1784f0b5c1b57d212e15192d2052c09a922fb25b58d63a5a7a854204c801f3c9b3f45bdbe9230e86fa94ffbab005bd03e2980960d0220fe2fcc15df6ba72fdfc4eb221bcdfea9a955be6487551db050a90ac74806cfee1255728dd8c90089e4523a0c7d150f0aa946503ca865f83da50196a75fa304d676ed0520d391958b0e3355f93215e3a74bb74f1613458e20167cf04f2bef4f9a8415c0a3973f02bda49fcf76cbb28d837efee9c71544018dee40aa07418e4aae9a248d7eead264aab85968fc28ff512ad5387eb35316b8bdb99c8d2248777ad8b7838576a9d27df4820591d2c7b34b0bf2beb1de3f004b55bc58de68ed41fa60deca24e5e7bc5eb3bb0da3684f2960dfcefaf1cc139742c66c1fb3a4857f4f46faf00432154e09637bd0deaaba735f0b59339d1497e631f1c1cdcc0fa8fb6d9bcaf877cf4d98466304ecef746019f41f7929b9b498d6a16d51823f58528bf7e2aab522cafd45203290c0308ecf20253e81e9dd2060640470ceb302d4c9686738545ef9772a00572e73d29cb8807b3a66a67a23334895e84c52fb44121e8934b1bd1763087370090679261267fed72de1249c09fe43bf83c2f4edf675df5e12f029404c7d6a598161fdaf98f687c282e60077cd0d02c9df9f1e9bd2ba0c88e9f8937cdfe40198f4c948c23a6f653ddbd805aa6bccf9e590d2c6ecd1a05b250cad0afb3532325f90157b6d9420c956e5b80150dce2ced701e5792993520cdd26e76352711c914ad0f234ee9c8e9eb0d3a2b3e3266b5de795cafccffbecdf0c3bc020fe171c5c691c2915997e564fffae771a9765a43d32e73b7a173295c17c28eaef413871f5b0e3a2c32368d84cf5a8020851c6d1119b8b727443dac2df0453364f9abafcd39f55fd3f2e64baff8b3bc38868b89bdf3198106730a6121fcc4c95494b855d025bb970d60abe2a87a5d22561a6a1ca6845fc34ee8d871d537d81cc63a27871d76d127994f4fc2cfba7a3a37b095fa9b68d8e4b612d844564163c29af3a30a2d3aea0f258ae6295df979b7ea43daec7149d075f69e121c2446dc7a80677d7d3c573500e3d5394bb1051916d6a56ee6ca653784c0764c20a2d02a76db3855a012a50a64b0e5b6fc8d371a2b76d2efdc7932faa088a173cc8b166442aa480f16033e1c3f1523911a0ac513d95b6045914aa942d3adbc1ea01f761f8b92d0531a68c512a3cf96317cc7ae7eaaf2bcea1d77b8154f26d874519c33bc7075ecefc6a45c420618ea6833c9a26562dabd6044cffd3d7ae3667ae7f979cdb6cdfdfd6c3abf01e1ad67179b1877e75addf326ca4e7d549a459f3dde2a60a75ec63aef8aa51c4f8494d0ec5ff4fa17f0d38c989fc7f7837dc5a9adaca3623807496b0affa8816510c63ce3d54fd650267d9e361faaeed6ae8c8c1b8f3e3d0b2852e34ab1fc16e5ade3202c61c54cf0ed5a321de1dd6492dc0349c45b9782742f4bd19059344bd1c1460092141c367380d4532e00047dfb79e764e4fd7abe8cfead0e4fcbff4bfac06692674b90cc9e724a2e480344418441603d8f0e7771af3fa925504a02677de4b1a1cdf0a1beed3124a316b8ec290dc18563d558e0b3e1ce5d910c5ea65d62f29801183e2321f7776d9e92564a7ce4400a62d2b7f3b9e463ab303cafcaf1538e5a88a3f5894b4b2b31093235c2af1de5087feb7c40a31ccc64ab4065c86d624a93c58c0f0be5a5fd5c8adb0d3ce28b27dc6ddd5e4cd48287787c89cb9d5fa45f64e5434deb9dce37e62dc288c14cc206a7feb6b83d17de6e789bbb9a15189d3878bae3872c4198e4e37545d10e1814443ffb9c1b47402f2f29968bc9ecee129071f9fffed612069efeb69667906c4e95d303b9d5fc2a9b7cd3b0e04cb6105ad2e9bfa68bd3c28f2d180f55465e782af48a53b51f69c3fd7fb365b0c83e17725ceedfbeb85601480865849f9dad82743ec9aa502f35757b8961405c52549e993f0e136e9335d2bec75e9be38e7cfe64e21ec8766d3bf987763a78a806e5ac26aa1a5f43b7e3a8a230353ad6d1590e79198a43d3c663c3ff783c63e4a1bf4e25d15b36e1956b860199a248e6248cd3883e3945514a73590be5049269b0d6fd96963f324a13ea4d4aef871cdd8538ee999ef86fcba9c6050058880916d555762470cec67ca3ebd38e30688ef62de8738c46178520813804b3bf8eadba03fc54ec3a740780e3e6f7aa4be6b8de7788bec533dd6b47aeafe981b24e13972596482958c9e7e34d56423f1ea0d1fea103cac0faab925babcd63e24f9eba2ee076f4807d3662901e3de57109967b9944d8da0a1e5948f96cf2d5d4f3ae618725c949cadc30cc95718198968f3c50cb0b9bae7902b9b258b8032fe19e42d509e84bba04f0d47cc8ee76cebcda5e00925b3caab10063c7c8ea312439e3b7544e6853f14d000fd345a1892c2f957e5ad104bc32a0857340fd996504d0b59c87f091fc933c295ced8afc6cd66ffb15edc8788390b758590db815e1d389122944056d2bd9733e4265ec0ff4f80383def90c53ee9151f138e3ce4748cd62b54be85d2f5b4076f12fb1a873eef7ae4aa373efae4ba7facd37d5d44e4dd80f075d1f780db79d6e28a8c7937b47437c50776783da37aa1a5f7466acd0a47906955cf4121e0e0a9badffff461e6c3c235674e01d36dec3980fa03b9b218304f00fa8c428a0bbf6e0b4bf2a7d7cebd79115be939a52f3926b79111e22432099eeb91fbe123c964d4181ec019230ac40e2b8efea14350908ae3c3e350ee1784671721f06722d1f75fccedfa24707bfa1851632ec05bfa09e23a414e473e27abec5dfd1d5f85fd679f9032db3b627894fd6a0472a4de7971904e50c620a14c821a7de97fb7334bda316f915112ff90ca8b90933cd78a51a72d148d93aff64a3a008c07e5dc02168bc6a8d296924a9a6ac0ada0a05d11a582edeedb05353321dac24674c2e76e2209978e14d5e19a5dfba0e98a3956a3838ce52e277e0fca5da79dda9976b3ddbfd32a92d4faa947f2c5d437c64e38fba4957d0a6f728f51611b2840a887934bdaebcd45432623fa185fda1280ffc019989fffd79304dcbb564d83af709282ae72114567029df82adf247b030e8279e3763b8e52654201b52d98110fcdf57a9f55059a0618d8964aecb32026b02a43f91d2d192cb43912db8803caa4027ecfa3c85016651cbee88a4548eba16c82254d832ddccc5a9d310cf3d9abfb0eced832c1fcd56f9dd1e5ffa55901b7effc504c644c4232cec118fb328fc0b07705639dce2d6d4c591db8493a6262936203aa05e35451a0292c173e46fc607cdeab6626a144c6fafac94b8afd85a522111fc36451c3932b47446628686889fae522779a4c861209b4faa4b61a4fd1185f6e082b0042555140b472ad5e3c73d32d6e9373f3c80f828a43f8ab93879b5a5229c85a1b1385d0a0ca8a0734f4103eea2e1cf439da77560e944431a3a2c991b059e8c080b56555913565e59332cf74135e7fe53678cae0f47b2b1ff093f97a243b0b71b34e5a37848df3ae121a5ebbe3195346fcba75966a460736c8dd95b1d57e491dd2593aeba9b3fce698d7352ab4801280db1c4a26a98ddc24e2ccf0f65c4d1e43df055df32f305b1561b9106d44ad36541bfcdaaeca9efb52cd95070cf132b041d39523eddfb9bd3d09ec4a9853a467d33cd05d99b79c5e035c847a3298cd41d6d76a6a4ff3b02ba211fc5e6b26b060da3569a088cd991121fcf334a75a58374e7f26afc5f4bc4b7905f123e4d2aa366fec3eb5b5b496f8d6bc19fbc54b7708e2dad8d9b2d96e2c1c3cce75194b9f211659b2be89cc1590c18de526116385b217ee78e315c1106f11a270f101943780588a28cee75023da0ab6efca0668ba136865e9529793fe05a379b723511a7ea90c4a653a6a7fe0b028ffc074ff57e3bd6c628e55f193a4fd7a864c5aa7d209cfdefa8dff5e9f8e045cba1a9d61d73fd8e3d078d3546be4ae26cdd04ac7602d3e11d8272e28a3ff9f0f6da9c79743b2bc4ba3abeb2fbc997ea6e32b654b270fcb85040093856fedf5855b3bee560ba76a987b6950fae0cd2d4cb1a84a994c85fda9e67e4b80c6c9d42055a648b2407e9f517765e8ed63fe7929628d517ae85b6210e2505d2bfa39d7b5a2ceaa61a736f51918a3b9ca28c0136fa5f244bb83feb8a94914d3fe7a420f905307dbeb4d2624eac963435e60523fa568977305d32efeaa99616b2e8933cefb8aaa00ba1f02a130e73c72140e560e073fd9fc3e066d0a7aee184e95ff43812f01656671b070014ff4a8d5cf3ef7b3157bbf0984c0853bcd64ee47169d5c6357642dacf25931d4b4d95eceaaf7663402a8e3872681eca7e6754a061e8559318eaf45fb5e5833ea4564eafebbeb9441f028dbc0a3eae253c8fad739533f06224326fa10723e578cd709b48430cb13859a09108f49ab463cd7f132a24f5e6dfd110ed92bd750c889b5aa31edf17e2b0228a737d99f27b8af8e6b559e892d625330df619e948ae83e8de82a3b54da1e43a56ba6bc7cc816c6c901f3d90699ad7ac025be9d7277ed04bf2d012d9ce0ee2e198b6065dc442e68a407ec9a60957d2b408af83924940667454db5e52c7d16608486e0c885828ed042ecf9712f2afce65e9cfbaddea49fe5ac71c83424814eec8557295b2fd715f259ad91ef5e5cdf4dc64d445f3dec36e2b4b85814079b653edb8c5fad0126f4315eb8b75912234e369e865e544cb42e81911409cfb07d70294732fa2058f388345b6fe6cebff5481605c7abc302969338a2dea17f7f2c2d4934a656007c570ccb92189dd567d328bc71374f50ff12a8e67b2e3a520184e94bd8634166458e7cabbe0766601e6701bd5e0f02901e487193b0868523e0966490f3bda2f6ebf5d0aaac5a761e36e6f14853b42ba785dbeabcf72b86ee384334787821fb9dff9419a26dd4e305013d4d16f26118019001fda816ea190e775ae25ef2794bbcf9461df536a1ea175d37b7058178071c45f71a48ed9055d3112f7067ca0a4dd621595a46a68fb9d75fa10abe6a79117d1ed6b685684d04f2456a09b014f79d7a47bd7ea5acec13cce4f0c14bb9a3929b4a5bf5f6b827ef91a52fea0e08a481b1c40791bae0ef939f953663ad099e0927925ea57cc63664248b66109c9248c4dd27c56cd15b77d234f04c130c613ee53e5a88c63ad16526172ceaa608a280365430216589dbddb5a38448ff630768bcb96f2be0034d6aa60919befea58214f935437c24a9c92a08b9ba72160f2eedd3cb6576786dff32f5f4a10e82092a093163daf627db0b1b3bb632d66346bae37f56319db106ba7d6969318310869df63db4efedb417360872f483fde41c043df5a8851dd879913656eb2e3a395a71c6fcd74cf546f482a089a78fb9378ec61d0c2848948d2b11d3d7eb24a7c23ca205f81a7c01a219364f6c5fa8ae8877f387e7fd707bd380135fe6953054e1bd5d849d2d36dabd7d40ca0038681f2a05078181444a627fdc9dd4c444d4a05496837e714f89fc16ef77df7736a346d7a61608909dac5306060a5e01623470f3dae785c6a0839b78d38128ac893bd4d7d8dc82080abd0b681e226595ebc75215dbb7a90d9766dbc686c39cf9fd08aee4c95796d63f51052731dd159ea859c10819d923a1d286705f726e8d7a22c91ed39aa26e7baa490c07d6864496676cc4f7093782dd99b4c770920b8dc77770c34b045832d3549e703d2a393755fc8b8c818e36797d14149f3e51fe778ac392152fedf1f42e350e323c5f1ac936a95a93212ef9e60f14361ac6dfc4653288ce5d2449c9e8227a3c70e37f11de0f3dcbd4ab27b39b2059e0622971bea407c545fcc1afd96498e7821f863a1130d733bc66d177dfcf8555c84986577e0ba0b1058db8f7011d72e9491a50b298f6914eaa00afe04d8114a0a4a6985a9a2072bf1669187c3e076257911396465ae7955612fbd47e6ace65d575af04cc6eeb33707a9d4d71685025ab97198621e7dfcfd63b45f113dda02f86d1610da066e2f96ef29f4109ebf532b84545c513ed6b4c068c1c673f8eaa966c85b5fadb440fc8f7c06363961cd3566a221f54d7100fcb71f5033933e573fdec7033b8424a5927b82d13a4cf0824598a8f5dbeeda36f607a10e80788f7154499d3c32c26f612bb2356cd5dcdb0841ff5ef94ba4d5d287ba60f458633ba9cbabbb2f012e9ef789b616fcd8866108b85853cde04899b3a49a3f49d33c5343973c02012f5919843aebddc28d912ea8c77cd497947ed9684ebe98a7c7f7b9f34504a132c3105ca2799c83af6e97ce345f3717934e76616e30044f56f4a4ff76f9d9e12573e6d15d377bf954fbcb2e978295eec0d1ccdc6aba47b9f4e702ddb9cae6a19715f23b20592e8db1966138547ebcb10fa45b655a7d9b65ab5a9a049ea912b5efd44a398fc72e14e5b67a72aa446970fd37aa4f139ba5bc71e68cb523aaf6b2e800890315a354e1397e759e6d9d72bec7c6c7541eca3ae129405a64d63704b634672c1c244eae91723b48c6d554a0923cd86bbcb5eba9389d0b7c247b68226e802d43a231f356ccb3d141fab0a9949a127b3c60ce2f4eb12fa67ff93dd245381182caee02588b65927d4d9fea6f239ee489c61cc0b596b93717c90beef577044d45bd97586084b113d0bf9df3915bd3150db3d34a754b2e03cf7bbe6e6938dee6785d3f0e94d8f483bf2654c1672791574b69b8fe952bd2a6ac51c9abb4920b238d2a7f23c0ecfa4bbc42f77c6c6f48c0f6cb5a783f48599e66a3620c7fd7fc10bd7962a9ec177c515bf8b4dba9344108040527fe742fc9d8ab47731bcb4fc976faa6ea445e8821db90a0a45f1d02d1a167f8ceb25b2a47f2e405913d6bfb9cb868d6b8acdc1a903d729c5440bc742237291f0eddf979ca78dae1686fe17494a9445d89013cf909ae041057a428868a461d6776af799cc1fa94f5243b7e58ce155f5d0a5e041e2d28b4ea0c233b03e1ba3bfafefc923f01d8cbfc4fc6302f90b0f41f15401af902ad611cf7774a49357ad700232355f3425b3ce5768694d9feaa79693a5b30453e9391a8a38d32174e62a1bca5646a205d8fee33168cca52f04a5ec7c1ba17ab7b169c7b5bc33439c8640ababd836618a22dd2fc9bc3d77126bd80ae48ea7d304f216b98d21bce50144bff8cdd475f5da677d45a32f191d2491e0ca7b9b4d09ffd1458c16622094c96e298d29597c4ca57cbffa8a68f437a9503635b09b65d4100fe73f07a418dfffe289a090102ceedc022275847573f26364230ed7a8a9a8d80aa40eafc7331232c231b71d6a24726cca184eaa5f20f491398167b78f2e75da046bf77d23e172fdcebc85e4efd35cf3f816905dda95b0ea681ac3a93ee053ee23fc3607fd1e2f8b3b9eb5432d4f05a9115c1f15c5e016c63d1201441861ac95063eded3166be8589ccac636ecabaf767c132b4bc7ecf93698421e8b0613094f7de28adfaaf3886db77c395131bc1cd3f6e1914e7d3f2b8415cf4e2e69fea433eee681b891c00b50380d3ab85ab7b5cd2c2723adb875a91718ccce45910d9b504e26d875f9966e8d670110793c7869d521e1bc4c6543ba119c28d0a5ed43e2fe4957dde8467b816c2cbc06ac0d37d2f2558f132c1d680a2109d1e090d73aff4e38ab2af95fe6d655344d0dfcc889399d34b15dc619476e8f7418831c3b043874cace7a04299dc5e17f824c6ea43928d4eaf7a1dcf36447470084cf062263801266d50b128e501b1e356458ee1881f66874b76d13e43b982fd7029929132c94cea262303aeb07f3c3b88e918841a4c113cd7c6d6e09a2039b2ff59bd1042a35e00eb18aecb5892474794a3b0b4d2f10a42e9d889fb6d527bbefd768b91cd846430825765898c3ea7461793f66cb0343aa3c9f1c5b5496d7f84a447bdd4501e7b1005c9daaf18e493a1a875e862f6c64c539ee7591157be9a35e83169646cb343cbc7a7e7231d8c708c458ec16b62806dc942a3793e6bb65066a3aadd8c5b208e73212e6074bc5ae7a72dfd3e859c44d89aba9e843fda193cc14b7d9c6ea81567e9da1bec422e7d268440aa2bbab6bf20acd15c0f19b3d455241b1e46014634e71dd6f658cc51ac3472a5dfd0683029c82c5600b45abc57e0d2a4f36177acbb551b69169095b11efaaa2b9b3ed8cbc49758891be29a63a844681f4b78b0890c3a8e4a4c0d6464e532fa17d34ca7093367e9023a33005cf168594829bd962c3056ce0a6127b556dd546010e7ab30c227993578a58400aead1a0814382387230a2dd356e73b08f359aadb3da049443cf78f9c04ef2c43a4648b8383db3a4a2c48faf3413f37ed47feba90b226b46a20b1e088119232b8b7b85599a067883641f2c2280895ee4fee4c0416ee1e463370690079ddda269db7ffc62e69e4dd423636c203368d8abe60e931d6927bfdbf1710aee9d27336f156676fd41a0d6fec9667e15d11ea2605a264d79a98ef4009e9502c14ec94dadc9e6d80fc2274bb42057de64c044939828276bf2951645074fe899ccc95ea3a3f2fdf19bae1e3ffb9ab8c893c421728dc1a5cd92f234c65be6929a44032f5e8085b29bf19b85f45d212f37a6881b14e33c084daaf3b057d542a58f8ece343d5734b550bca7bb213f7327fa710b9320c62de41ea99a74abb8b6ee5eac478e669c55409a984945347867a564ddc9c1aff9aff9338800e878deb575ccc1e696996d69aa3ccad973c1976ff80706b0f229f3aaef2d13b143d0e58f68f2994a86fd1cba6c773c15b3b6104beda65861bd5143c0b38ba412a147d20fcd228bca716c35ebb11f97a8403654000cb981f5e22806ac986bbf3afecea2c7ffda9b8616abf631fbe930aca3bcc8b808f383417f5ada230469bc67563a8d0263e8ee076122cdf61f646e24c88f8416ba4612f7ec04f044b1d4860c42d42b3996822311c170a4ba57177bf82d01f84688fc25e5725676481c2392fcd24a9968e9eebf2423c6fa18857fb72bdec868abe28b8d5338083cb50fc6d610997bb5d849a9ca2c6fa3943eb997ca1cd3fc1cfee1d9831c81776a452dd37299880a5453afd2eb2228cdb4ed330d935f650b763f17ca687d754e09070597d9e3cb296688176fcf6177c4ed47bb59e0d750b0fd2e0247a70e7d7032aebea36865ac0103ed9a52868a9e86c2707ce5bf481ea0aa2f3e1b85db017e8c7f9ee491711f61ec74ddc399c4143d43b54581fe4d1936023503bd8b847aebe208ad4b64f0d885deb0487a0e2cecd243ac90edeebc0dad54f069f09b0c4f38a07ecdce290e32de9d8ad3d6740a315f11535e1c69ee91cb0aa53a7b7848f705e0aa313c63d5673b5f6c59c26893fddc25e846fb874b8532f99cd1eb1d25ac3fd0eaabdcddf934984883d68c9e193bed8011ae1910800db2742ba9930052524030c8e399110dbab68c3422d7e9d7cc2fec030cf0b0cb3921b4ec157abab341bbe2e6a0d7c45237f601bffd0ad3cbc445c2a65b1f5841062cb85262c72891c20bddb101dd78a9ab885907f1774c4866696ae1e7a7cabdae68897234f45405f750479df55d779ee8d7c1acab609c78858ecf612421b67bdba1181af5e349ac1c132677e43372e1049892106ddadc9b512df914e53404858f59e7cd1d3e91ee8037784e189f9fe9dc7ec1fca4382c2b3b4c35fb2a530df6ef32ed5da57e4fdd4a08e2a02feff6f608542cad367a1ac5a80343ad53407958d43c814dd9ca8501df8a196a51f8095c2da442f350bf71d3d8dc422a13b6e9f9ce5dc1b80bff9ae94d315ae00b56efea227929e17b930131417937ed1da001af94f51ac614b50db47787d7d7a24f7252b1269d172313fe4a9b2c00204088a0360bff876cd5aa50b0d8f6d8ca01ec703b0e53a947ad03d1f438f91f47f7bf074ba3d2d2edf340d7dcf20bdd4639a37f01b0cc92d02ca42b5f3ad8a97c603f292094e59176880cce2a30f861efe83b2d45d47f628236bdae1ea65d251e646cca6c950f0e95f50d2e336b2e55dfd07ba69e1d7007375da7a1e4d984a9d8f012a75cea3856830a4d36b8e268767c8a862cd95b59d3006d6f6955bdf05a4b5dd7c80fc6e578345024b0ee221222ad261aff45f69d7b8dcce002dd46ce6fc06c139a675ce19270440a515ffe3a3ed25a0713552d4911d82eb37dbd5a5d0acbcbd5c66285626de34e44d71fd32a1df60614bf9bd0732485f6e61b920a4a27908e492be1f90e7e68ef07862789feff678ed4b9844a40000bbb3531fa8b52aad4ad978c811c545958644408fe6faeade7ecfe086fef6157ed0cfd53ca56fe5b7906e63331b742e18ea8f7a9542e1ae3fea550ab959b511aefb91bedb51e84677973d9487028f959689f794f1d861b88ec7bd57ff50b6e437b4d2e5b9a6f077e5703179742ff330b07897ebe96231bae906609daf7730e6ad803dc38f7cf7f4ea32259c10f137d343e6d4bac59611ebb8528c5bbde8f3dc8c4fa4125b4a1d22d9794bb5d95882fd795dbe4f9118217887cb8d0a5de7704997454f7ede9d68f6ffbd8f91d5f05a5d03a6aadf1e437ee1c4ae49673535327b2a986823db1f7b245618dc4919780a1d586d19fe51d6880727f9a9c68dd73532dd9b71b663a3f2d9f0de8b9e6716d85cd2e81429cd7685c18fe548754918d360e79ed6f6c1db062ff94e9a9e99c7e4ad60a93e1393175eb25c87f073170c2f05c1c65f6683d7c1f17fd906e8ed43e957c80d994c4814c4c502ae8ceae4f9ab8e955d2339dffc106fb67c1a42c680def6d6a56ad1ca1226158c413e4afcb111cecb75cece1c9f6f55b01d740e5dc2b15ae18f4aa78adef73d10bbb69b070dd5eba8dac9a987a3b7be1574f1aeedc0db605980b7dd19e1007b77503c7a8290b2cd3b1f65f824025e1cd7634cf69bf1c8cfd7a979f095cfd94b45fd8a015a9afac815869f9e6f8c02d5487204a1e34db69d67af3174b70c20661f86b3f8724abec0a03b1224645a333a900623ccf447d30a85e45a74dcc73b525e31f1e117f4f42d5f48689fe0dae20fabf0ecda572299c99ccc833cbea1c38c30a1518dc9127805a601b62f9a0fda0f4afef770712412da3f590db951b8a845d6a5f82a0428c8717351dd4e09a3e32c53a18f9340969da9b92973a440827b9302cde5904225a4db47fd3d0cb5aba740181f5437ccf8c8bce79344e448b2dbcf15f7f74d170a49f7802a106bc7827050f00f12c0476a48e27acc6082bd94d221ce4f94b6cda17817ff90257299b77d56d5bdd64d5accb80758f43e3ebe8ddbaf0e223571a7bacb34d98be07031608cceb18dc749ce3f5a4805c8ab7e42658f0886c1511bc55ea5654bbdbf829cef41e87242931f83e4bd403b2f170af47fee1454d446f7a356b88c0091518e0deb39740bb0b1853b78aa3b5fa62818aeb05b7e29387c6a37437cace113fa8ecc8443b0df58a4a3af49a1194b05e5730f4365f312788acc778b530ace41e87a3b52ba1a9e66d05ecf0852cbfde64ee0ec40c86da2a4d9d0ba5d89797bec9f98a2c27156010d7407f732005f4dbe0163851f5ecefb4546f7fbece117977f0b4f31a5fbad70368b254c3a386991bc7fded5a8cae5da1bcb7d96b14f8f6cee0787356144999e83935c2890b369d2648a5d3d34913827ffca0550a964590a8971782fa70f665d5e90745b959c304be0465fcaf6dbdc096d2ec801245429651bee8253691c43fc751ce3692661f691ddca70e3ca5093f35fbc325033722941206f0eed507dfba25fe2c74f2c376930c90005864d17859c114bc0f5e7c2e5130b5913d89c4781e543d4fed55b6d17e8f5c5ae7de547e4185a5c20b35ed12f76c2476e6236764dfb1680f7b1c1126877a6d6a7930cf4ec5f554a5ed37d1559e3ba30f3fa5b6b25eb4641b61a809285a2672d6830bc8b6d55fb062c83df2635db0111ccf58ae5f9c661f9e51efb87f596fdb1a7f93b55f04d408aa3621445e8f5e4cbb28f0d1f1ffa50487f41a721e867df5007912bb50056e8d9b5d44d955b98a68dab1a0ec4822f5902e4ba77d8e23820f3b74dad05270ccc3550e564ee265960b2cb0bf771fcb86949fcec803eaf4038eb48a2ecefc1177ee13eaad3987d89fc28a09753395c988b6d49e6a672c9724edc2c076e2facc5ab62e845d323053c4dd1fbb8cb5afa029cfd73cec986641fa5b3107f533bb6810af16ffb9066ea727da805f7c39343e6d4e91266c767392232591a4c193c239ed1ca0b0b2f30f2718e74496b7f55908343f77db7e856d3b9900edbcf59cdd156ed1f1f90384de2aed7e35cb6fd4c8c432947bc7c5427ed30ee7a5bba5f77ddc7169ac16cf653f75211cf8f8335e8c610536e8f1daef1fc7d4feb0decd39ee3644e226c9052e568df49966680067bbbb7ac87ef52b73c2a152c642a539b16de048cc24de6b3072f173770e1cff90cd0b11accc7e24b8bd81ee4c46a1c7077b03ee0aa6418182c13d4fbd9d667f80f315f2b92ba28c866d15032b63a1e69bf1a4694f78ea3bde93e6a80ea00785fde318fd122dc6398909ead4ff9ac4530781513eebc108d409c588d01cb0502bdcdb2e3f64ad0898e8ff57e57b2129f20ba936852cd55bdce6b57e20a83312e24e31e6f42c67b19b681cc294a73e032f8a3d8bdc5b17dc6effb36d7055d1d9afe833438447092b575ce22aa0773a530511b8141200d5081d4f4d297421b19fa27e6339945b70918af1806dcd39100697067ae4460e4a89acece935bdfbdf6d795ced48c707075f8d00a58eb629e2a1efe886809ec1c39d6cae35e524eeafb631b30b404a433aa02f190264903345e14ef85c82eda65ceff71ee311f2657f315b1e729803c150d18bbca3bc9e0f5a3528889baea4a3650091f62e2432843908166c9acc493b121e6c692488a30bb140f9fa549d85104922aeab1611b729f006b50b3e355180cf5851c33833ca8613fdce5046647a4303b112b50f6954f67976bbd26de0af45f3ab207d3c333a9abdf8616db3cd4920362b40b90543dd211f84800bfe5128bf5678785f2b4d880bc460d8caa8e8ea4d66358ea32ae8847400e29637143d2f6218cc1ee4e26c65df7ba4a911da04af3caaab6075b9e5b2d901fbfb6b1e9f4e07588ef135907a5a9d8775173774f92f358d62bfb3ef191c524b1e69757e2340dba79eadb0c2bce79d54a02676b5cf16bbb6719a59e1678dee7c5d06fe621cf12a93a8a7d09ede273e1bd7127b53dbd611b62a33c8fbdf2623cbcc4a45d2fb8917b222e800f7506540daa611a4ed4bacbb55394771de796b9b7a32d10df369ddc51b736de7fcd456728f353c7d49f5a8764168c027841fc46c120837ece7d31156b3df611f9b184393c26beee85724d8cbc91968dbd37adac0d1ae432557736e040017b3d798aaaf861341589a5895808fb3321b48a08492dc7e7ce2dafa010763bceed3ca294c80eba718be4468f4fb45c614f0357159a1ad0ddda84e04d030f5b25f81d76a349a0aa173539f48f83aa7120fff08a4650491d445c3dddc187b28676e9b1924de7df11878d22c5a3971d9e285d0d90c158341d159f7c8ad6984d3f99893b1164167f8e2d5f5a0c571e55ef1c10abded8bca5fed191ca6e711343b0317218b39b8eadd4f11c48026d80cbabc9bd056f3bfd59a7d649b0355b67ed4f942c9b5af7d2226ae81b9180d227d7e0ff39dfd00bef9a7de6052ea0c1a3f65a4a72ae07d42510e605d1b103ef81aa15b193ccec325601d9bb697639047d4040aea6c9266d2af1ff64567a65f142d3e28224c0a6a8fe54418d6bf9903ae29aab92f407bf8e357edc065cd2cf08c60da021a0ad29c9a32873da926579be5dd8c4bfa28d2867f22aaafc0ca7a82e887105c07a0f7f935e4dd5cb7bb185b54a31632ae8cc7f7d2414e4e138e108140925cba51a3ef1606833c3587840203c6a7428f2574351b96873e1e84cab490bd886af019a1ea6724a73169ca500a2630d7b588ae5f08913be4286c65859d97fd883c7db22d95371c512c25d6a5ac9113fe1aeca2dd427744099d97227b25e95dd1b719bd4a01b71b5fe4a019148d26b6b5eb6dd701d0057998c17cb6a9fdd299f37ab0f4fd753e336635fc1877e157495a275e072747bc5a3ade13ea18875b44eec1c74128b459ece6f9257916653157291a04667ab24958a2bfacbe78be45ac41bd348111ea7b172814e2c579d190253794f66a44c2026435f3223620f5adc33c9f0c4e1f13b2db9a739e79cb74dad53e25585914f32f2b160f7d8e320d085e20b952898ca58ebb9495d06750c1e391bfded83963ca16a3adcdaa67e994e26d71d6281a991c230f347315d53be0dff3e5f59069d573cf621afb0ac75c6769b6b5863c091fc1ace7b362645465327b410b5eece3f5e94db4cdb7c3c50fe1db105ba3a06142825f66049c80d0c2d97d50dbb4c5f053fafcd2efbff611149c8566f518940bf120d37b25daac29fab43045fa9a952b9a02d8631ee8e03d7152c47f19987e76e6f22b9f5abdd9e7f00da617cf15db52780b9342eec46ed458670781da3792a3c8561b9abaca36c28be625994a152cadb7a703cbef6b38cf0b45b9062434c61685e477e4b46058623e1a2378f0df57ffe8a57f7a5d6e91cbb8ba7bf487b308d20ceec60a01d8505e8a6a6c8347642ab7ae5e7783c7400c9c92b9e18f9aa845196f272305c1596a6aa06de60a020f714f2a964971bed3a46312d4dbf3ea6c6d0eaa94f368b7b52a5f208cf474671ae9863f560f735b6a9c28226e2ebd5479f65c83cb0c4fa219faf66a09b6fac8d2ec6f7c3c6e4ab0a56902a0e0464a71870f74b5949211455121772816a8a26cccf5a73726d9313bcce3a2a91c9450d3cc384bbbbae1a2bb43fc6e33b186d5adf6653734a6a9edaec0904335cabece977b0effa5b6c4e98eb60dad72be6e9eb3b4673835dd3faf6eb0ed93165e2211783485f784328cda99bcd14701d1bb147c04064c9d50f5383047c56c026bd32d952fb8a9d5946dc1e8e8b228c3416b232e19d21ad0a02b7aab8eec8cfe4d994fecd051cea977f3c16efe93ca374d6d1aa66101d6ce9edafef8e47cf0e2500a49ae2bbd168ee41cf2711aa19ea6e77a29bb7f0abfaa8a2c063b46510a97963e96a098bee8c85cba2e04e1d73c5a3700a669b7f57290f4fff3a992b39d4d36b07cad2ac96047e52883ead6dbd00e00c90f5c8fa72dda311b96ae8327d95029806dbeaf3527e53fc725ac1257c24189a95ba81f3cc604c8ea205852141ca7612ae50555913ed4c72d4aa57dec08e8ef0083b95730550668c6fff9981e95aa727726576eaa90fbbe6c177e5e909f9bd351aa1c835bc622b60a0897c7ec8a3f1c9a552418093612f8518138d02234c606e1ba5fe2730ea8db45591e663ea3862315785a74a6eb3706624798ac8a89bd5055fb4cc1413a92a15b55ed106345d30d1c4d9d0fddf0edbe3b7c797265dee591e05eca992cc9ca9fa5521897e0e4942db4abbdec5c9498b663d45240ef4085e763e3d7b1b2b6a5ac4d9c0c55a5665ef8634e10ff4e6a033762fa764768c9c35ae65c07d15be6aa037d515596cbb311175ce2dba840a85060840032bcbd6971847198f11738fff91e04bbbfa4ee7a9c0bbb46dac1df2a38654731b937cd1552082c907e2376ec7e9a43be10f90a621c98515693293b37e4542e365ec52b592fe06e4234e44e072b46933de279365280eee05c73df17abfb3e631749fdb1035bc0f20a39b5da5a2cd53a82a7d11f5b521b985482f90b88abbdea8826caf2d3c985539debf76dc88291028860e83bbf7748b9d25de2884a49bc6771484a47389699aabbbcd6d5621d804ba4e1abd7a76ab2b351f063211caacf24026c17fc065a2912e98bd1467de1d0bb7b15443f6932ffc104634c6365fce4a79adf437a3e5bd5bf7ec8bf9a511b1ae3481d586e0173d751e97c8b926b9b7711d26113de0f88858bd04b667c9a8a6da5e3d9748b55f06b09969b4599db6dde288543d3202211b659e7fd2bb8e9e2544f55b0a89900fb38f7036a27a4fe4c1896ed7914030b766cd7bc3c477b25dcb3baa870517c6fd755e755abfb017fb25772215b37560e7679e69b032e6f2833aa246b3122f16a37421c80aee26e57dcce797be3e471519913bd15444b6bdc7e0eb80ad9367cfa997cb4e8cadb4a01b0b91259e69900f12f09f461cb6a314b669ba37c938b85262f55c61e1472fab6726a27a6f3eef61fb3fef97c921c332b32af4c6e4cefe6bfc631b385d72438cfa31e4580feaacafe9bec55d3f7001881fac4503e6c58b54b7988a4591058444f8f42e56e69e1fe874afb5699a5fcbfc0f9bf6f8ecbcedd8e1031e7ed5c2ae454c7fa5983e3c142afe44f79af8703128d00912ee7964ab1381818c9b8c3c34699871f640349b16a01ec67ac6640400935893edec5602cf2b9ccc965a185a15567e63f9ac6db73b24775a4ba7edcb13c581d58db7e133b9faf2f2fb78428302516adcf02fb322aba4936346e6eeb39f7366517aa1ee9b6433a3ce0f9bdea0e6d88a369ed49e1e7da8a76ca96adcb0609fad512cde90495c11db5fd40f10fb2087c614f5dc4921a22da19a16d23210482876854f301f679c87c8e319e897720b92f3ec2c3b0e790c6e086e82a8b1c0ea8e289652"
+ },
+ {
+ "address": "a1fb5292afb33b7d8d0153491de9c55aa6236c2b2adb9f085c54f2996a236bad",
+ "content": "93846578fa652078b811d1c6560616c2999e286360b7fdd151384df85f42"
+ },
+ {
+ "address": "a277fabda416986599552ddbd4467e18993c7a1e2e4e321817f62dd32c185302",
+ "content": "58bccb54fc2a00badf7cd88d34dfd9190d7c5f4502b1b8ecedccfd2f56d0"
+ },
+ {
+ "address": "a28068f502aa41738121c0f7116fc5c7e0a2f258c291ef60b8325ceed04c07bc",
+ "content": "da61bd5e2dc2677d864312aa1f7f5e044dd2589616c07151d4f99338a378"
+ },
+ {
+ "address": "a2e24ba9d6878bb9e6e63fe7eb53be1d07860edeb40753bbf5f1b364002d1a34",
+ "content": "dc61c4ecc0750129205dd78de4188b24e2eb5bdf8fc5dda0f6b8129c1ba2"
+ },
+ {
+ "address": "a33bf85249bdf0d4e3ac6c9bcd9a1db0cd0a91878381b26313d35d6e5f137e04",
+ "content": "76854c1331c58a01c6ec5490ea2cedf01294f26f477d8270bbdebb8ecd77"
+ },
+ {
+ "address": "a37a346a80e7bb28fdd351e26a1ef6b8869049bd0b7333757b897a7dc26c5ece",
+ "content": "880c9bb9ecd96daf3bf27e8705a92299e3465c2cf3c5de597b5d69155bbb"
+ },
+ {
+ "address": "a3a3b4455c9361e7bd1ae91ab3bf5b15017978f0e1c84f68269fa856117ade69",
+ "content": "5299fc0360a3a8bfa9d5134b0efd794fdda4698611a1c7f65c31ae605f49"
+ },
+ {
+ "address": "a4bb679a13bf3a51a69dd8434b6ab804410b11f68692fe1b55d40f08c060186c",
+ "content": "80c6847955de1a9c95840dad71c1b7a2ef6beea87541982f04b39ba39723"
+ },
+ {
+ "address": "a4c3b1182332dfadb07c461aa4226fbec806fad16585af2e804ed4250155acd1",
+ "content": "049b64101930a5a8281be83967d5750bb2f17754f9dff0148c3bcd55eabc"
+ },
+ {
+ "address": "a5032fa20b581e7a0487739cc3bbccfd96b7714857b03a94256169bcb0a7660e",
+ "content": "94e246421060607f25f495cb0e2b1a79105bcc735f170cce75a016cedc55"
+ },
+ {
+ "address": "a536590a16d17715015c103bc2c9ef5695f30a025416126f3f7b7025a1445bd2",
+ "content": "4d307178051dd9c87faf50cd213439732c68b83b314232321559bef52bec"
+ },
+ {
+ "address": "a56a1984d2b57a7e75958c1492da681bb3b5260ab4b7a03274b6d2aed1021ea8",
+ "content": "cc54e3c7fbc9fbc04e6c5641410c2bbf87ea26ce36523033e8b9ecfac3fe"
+ },
+ {
+ "address": "a5b6cd3e235eaefe80c6c4f78f5bd73d45ea135e55402368cf4073cebc8647e5",
+ "content": "46fc22b34454f71ea2ceb8179fd291648ee82b790d6cb57692b7d075cb3a"
+ },
+ {
+ "address": "a5fa5d883da0df6a4b0d433dec6b995e2c08543c250fcb91de7ecd68316e34c8",
+ "content": "423f905ec4d1e652be453456c613b3135ba88c05ea288064b7af396af79e"
+ },
+ {
+ "address": "a638215ee2b9acdd201f8d6ef7fdd949a84c2a9d72417fe397ad53881ed8f53a",
+ "content": "c5a4417ff05b7c1768a5439f903f173ee3188660056e8a1d3c524516418e"
+ },
+ {
+ "address": "a64ef406814d91e58f286cc7158eefee2c08db94d887bbc6061c9b1bbbd3d92e",
+ "content": "559f67de1de698d22484d0622e217025c34a92d877f9ded6ef0d569fbeaf"
+ },
+ {
+ "address": "a65df49631c890c729419490125f55f85f72964453799cac5ca09a8441190f5e",
+ "content": "024358ffe0c58a1cdf4a9d65342e4911dc0c5e6406319607b3be89bd2289"
+ },
+ {
+ "address": "a70156785b474a98865d270836ff97f0aea7708ac8761ecaefda2f9c9109ee56",
+ "content": "14718f614f9f86c78ceb3853bbf9b49ae62e29867a550dd1f52b90248800"
+ },
+ {
+ "address": "a703b04a50f3743a08a9799b1e0e08a0cc7724289b3b2be795e7a9b0ed77c4e3",
+ "content": "4e38ed64763f3f07f34270b1e66a47cb687e7a011a5f5387961a809a80eb"
+ },
+ {
+ "address": "a71fa6a4a927ac6a06b935689465ecb3dd9d37b8510ee66efb5fbc574043a6e5",
+ "content": "79ba05446800ef5317c1cda57028d91f9df9c4454193811b0b5379d6f58d"
+ },
+ {
+ "address": "a7924316f33b416dbb2486069facc0187fcf4f1dc8384e55a30a903d6c4c332d",
+ "content": "7880f96e0dc70aaebdb5f8dc040bdbcd65af2390ad76a0f630414f9516d6"
+ },
+ {
+ "address": "a7970b8786e76ca3811aa79cdc562903b38454b3bffdb9633bed8eac1025934a",
+ "content": "c7eb1b55f36f1ce4d55bf48650e0243fe9fabd46ed7abab02086ea4119d4"
+ },
+ {
+ "address": "a7e0434658dfb7a699c7ceb138a8dae4aa9d9d73ba5f03e5d5cc3b190cbc71bc",
+ "content": "30afab580448ce95d8220030bf47ea34cee473c357d2a71725175d98c6ea"
+ },
+ {
+ "address": "a7fba900c1ebb85c8a1227ad4d3b32b1bedd2362c5fab3c1947a42ecaea9fbbb",
+ "content": "a692054f8b53d5bf93be691353da079502b2eefb68b78a5c27bb92979e68"
+ },
+ {
+ "address": "a88cee7c38c77432ca063eb560458f095ed656161a14e87f72da8081f8519f5a",
+ "content": "4763e475e075aee47ee70739ea41c7a63081101a5d7101f31aa9ff9420bd"
+ },
+ {
+ "address": "a8c26344fe864b578d88257e4451500bbc2b10a273b95c0c1a5c32af05b91ec3",
+ "content": "bdf803110fabdf6f422e78ee88602b21359ccf95d53e64c66b490e9d9b73"
+ },
+ {
+ "address": "a8d5016285e27bbbf7d46bf6c30891eacd62a24935d5b0c90edfd86f3d35d44a",
+ "content": "1df3dffadb563485c1e16516e0853dd6519821e7ac1fc0a59343b94804e9"
+ },
+ {
+ "address": "a8dd9deda0f27ebb784f435688bbf39a05a1c9d44fe5251100fe9428edd383fb",
+ "content": "94a32e912b234897db81c29e5f8566a18ded9805958d8020481e5077e1d6"
+ },
+ {
+ "address": "a923a86638e0acb61d6058065a85a971f7ffcdd0b3469eb4f181c2be21a42a52",
+ "content": "f3617b1160f3c594e9fd45b8c74774403530cc06ad925ff5bf8d6cf5e85f"
+ },
+ {
+ "address": "a92675bcae363e8222707932da4b31631c42ef320c81f8b25210ebf8b5c0497f",
+ "content": "a0f04f111426f7862696ccaaba24f73b4b62be419e4f8cea78b827c1db5b"
+ },
+ {
+ "address": "a944a734bf6bfe972d58fa343313a6fec03dd52d6b258b2c2ecfc3db87fb3614",
+ "content": "7baa08debd3410efcc15bf129d1ee06a2d596f7192a3f85d5dcdeccd8774"
+ },
+ {
+ "address": "a9fe624c52402742e554807e1e7e3c68b0d4998cefb32c56ea81660f6f321b43",
+ "content": "d1a5cd2a43b7b4d218526a4dc275f6e237854f37a8e1bf9e041f963242d4"
+ },
+ {
+ "address": "aa1f5b95d3914c5fc04bc5f47517e130aa63226ebab64a4b0ec4d77ba0294985",
+ "content": "ccee715e0154ede08548083590995646f46c148a6fc1827ae39275dc3ede"
+ },
+ {
+ "address": "aa8b38c2307ea87b6f9315820a48b26683f80b85618a32c0fb97288aeba61327",
+ "content": "d5b97da3510ec0c2289b11c4f0dbe561a0d3e5c2b99a5ff9fabb3c20905b"
+ },
+ {
+ "address": "ab30af4a8cc9a8548e9d85e0d09b993d221aea5a75fd82035c28521099d83359",
+ "content": "54b7410333d94386bcd107bc4f9d56dd2271d48f49ee58bede994ead0734"
+ },
+ {
+ "address": "ab4d2c84b937840cdf8fbc9b4473da061b9a64bb782ca9f31684028eb586ce89",
+ "content": "b04d8cdeaeecd80297ed1ea9c34368ba7414db9b252fe67abb57cfc798d9"
+ },
+ {
+ "address": "abf56cb790ff0d0a57dc3891ed359539e0b65538d726f4311624215c26138295",
+ "content": "ac861a5ac2054c01c9feb669434290e566f0d192d5ca39485f9802b4137b"
+ },
+ {
+ "address": "ac138a8c3ecf019c99c7e5426b0d2c20fe08aff1be25fce3cb1b5409f4c7d3b6",
+ "content": "6b4bbc36b83e07bfcbf28c395c5e36212a1894bda207c93794a29932ab9b"
+ },
+ {
+ "address": "acf8e8c89ddded3922b2d77903a8149413a6cd21d0b64a839a5e4434554734c3",
+ "content": "54a37645b65e43bb7199780e4f59376280a92c9dd59922137854f7505479"
+ },
+ {
+ "address": "ad487b8a6acdb940e5aeec90c0b166cd7534bdc6a47655b0f54e1c67048491bd",
+ "content": "02bec083b740ff5e41b452f69f48f5790b237db6614d242a634275beb7a9"
+ },
+ {
+ "address": "ad85a9c96c11785817187752cf3b126fa3f1f08135c7aa5abc88bd93031d7553",
+ "content": "ff934f2ca9f7278478c547cb7a407548cca655f5a15313cd7e5be9a8ccd7"
+ },
+ {
+ "address": "ad8cd427a2ab15b606eaecb4f2ea40e676315f48bb46729d81420e4380a67a4b",
+ "content": "bea14f09601549c30e98328586962d5ca7fa4d342225053459eec87d323e"
+ },
+ {
+ "address": "add58bb35c2fe6376ecd03fb71aa6c7237498b03036ca6df2ffb24c85e3bc16d",
+ "content": "9c82fff6b8a44f6d490de18d50a01212299daec4bee3d9bbdc9f1013470c"
+ },
+ {
+ "address": "adf46ad37f6d09faa2071f994d065bcaabd3e0d1607583761c81bff248df9ab9",
+ "content": "7da9a806803c1d9d6a6f5d19cb2ab79b3943011476d47566f6f456923532"
+ },
+ {
+ "address": "ae3fa2d697590827448fbfbbea4e88a140bb21b38016db8b2e611dc277ab6f49",
+ "content": "029e79b96a32859c71dbfd76371da838b48e24619fef7df0a3c8efb0e2a6"
+ },
+ {
+ "address": "ae4f1ff859266e08df5f982bf785f1d77e676bfbe39a5487c7630959ed6fe6fd",
+ "content": "0404035e34db477ac1bab4c9281d98a69d6088e56fe187108cb68e019f6f"
+ },
+ {
+ "address": "af3350a3ebf08dbf77614262362ffb6883c8c6471585802df158278d1eb6ff0f",
+ "content": "a81ec117bf91ea23de02491ee0b68caa0fa393ec803fb77ea5cc1b0bac89"
+ },
+ {
+ "address": "af536c6e6f964a2e5c67158477dfeb2e3bbf1cacce4efdbf33d3f18c67aa26f4",
+ "content": "aeccbb4fe3ba1c3f003e617a0c242264068bbe06971129540bf0868a6741"
+ },
+ {
+ "address": "afd0daf901ef82edd5f759d067ab2437700d67d8594d07fca60d0aac7320b16b",
+ "content": "4122e254857152a7aa293fd27c004d12761d73f60e50b70c1b68d9ef6a62"
+ },
+ {
+ "address": "afdc54f0d72630b464318916f87bb5db3a6eaafc398dfa6fffaaadc89c6c6567",
+ "content": "fa82dfbc6572b91f2aa50fef498e00f9c564e14391bfaac5cb8c26a7dc08"
+ },
+ {
+ "address": "aff3934c56dbeec53b70492ded80797ae0b96f860bcd0a7f8bb28beff287f0b6",
+ "content": "5c946cf5b171cee61e7e96187487d62fb22b3cfdb71fe4c69f6582bcc1a0"
+ },
+ {
+ "address": "affa548b1b199c8e176438aae10b4cd3dec8740051b2b01d2a90d44d6e92a9e5",
+ "content": "0346f3ba5cfe7c9aaf73f264410e8e34f8600c262c34ab4e266d2232ddaf"
+ },
+ {
+ "address": "b05b1910b7e929903539d527eb1119c981abe8aa8888ed5d7e3b82f43437fb33",
+ "content": "f562b783c057bf7ef436b8caedbd0f979f199c0d469a464b87164864da9e"
+ },
+ {
+ "address": "b0e8a56585fda0260159184a2eecc969f6f583b7fd1f128bd4b7229c2dbba3f0",
+ "content": "3f8bf69bc394c067c39752f714079a10a43bd1e59ea3ffe1460ee6002eda"
+ },
+ {
+ "address": "b147cafa1d20c300346b5dcbf7fc852f1924bd4b83568083a84c6c64003442e9",
+ "content": "484352cd141ca15e1d15ef3501f40c5b910ca737971654b72e1c51043715"
+ },
+ {
+ "address": "b1570c2d7b825e4e881643930fa356b50e9fe460ae5436cb4f270ddf330b5e98",
+ "content": "c4071e3f06ee80ffb0c01145178cf7dd4a940c6a39160aa1649f18ac3f1b"
+ },
+ {
+ "address": "b195d8cf713f5f2df4ddca9d460104e7ca784bdcdcc7906d59361450620b7be9",
+ "content": "255d8d0d7cfa0a2606c9eb6ae1ebfae4e6422cd519bebb405ef149d1d3b7"
+ },
+ {
+ "address": "b1cddf5ba5c76474a099552e0ec1c25ec55429faf6dfdc6274a9f42dcc4f0e2e",
+ "content": "2d128f1c2107b853bc69c8d7ead62ef89a6c629b8404c99a291e77739b0b"
+ },
+ {
+ "address": "b1d8b2225031d7252833633e9f2673ae4c088475825631c0415b3e7cfa4db461",
+ "content": "d43b9ea50b70e460dfc27ef645fff641e840c7d82dc1c33d9efd6ff75b76"
+ },
+ {
+ "address": "b1d900b35e96bc1ca2b5ee62d72d7a352d61be814b104ae551390307ad4136f2",
+ "content": "f6729abb0a3540bfa8dc26b6a8968d8d9307470f1904a8c1b42bd9089802"
+ },
+ {
+ "address": "b1fc1c42260eaaf3a730d21106bcb6e1f5b66b808fe777bf79cab971b3ed08b0",
+ "content": "b737386f866b6a41d421937c6d871c5901e8810106194a85b20a5a356e85"
+ },
+ {
+ "address": "b27bb528251b6aca5790a53a8ab82ae0dd4e816a2b2df2b699e22e140efa844d",
+ "content": "11a67d4379d01be20eb60cefb1f327e064fb62158d801b0df99c87e75bbe"
+ },
+ {
+ "address": "b347de8995248eaad2d5552c22c644227f2a11b4f9924eb5ab578a39c3945ee2",
+ "content": "faf0f88b59e8e7a438e4a8310f4075a2257b5138fa0b5f07e53f05dc6e43"
+ },
+ {
+ "address": "b3be8e9daa9492032cc2a2c6835968f1b12a5d6a7e6e2b2ddadfbb3b4bfd0aa8",
+ "content": "a17c26256278a8f3ca25b5f5b90a5874e196590faffaa69f7315ab832eb4"
+ },
+ {
+ "address": "b3e82d4a26174e8eb523437b90e62acc2b70aabcaa5e7cfdff7eaebe388e8f55",
+ "content": "eb538bf6297232a22ae09c1aeab1908d1ac9ce60d618bdaa51dc415122cc"
+ },
+ {
+ "address": "b3fd41b20fdc61276627f1de436c03e13e94542c424bef49d900e8e54a90f873",
+ "content": "8ed203ea6bfe0b1d9e146cd6cef2b056e56979303535a795a1379d49f5e2"
+ },
+ {
+ "address": "b4121392b213bd2af7cafdd478737ac3d7c36ee74235c07a9ffd0d7889041f72",
+ "content": "a88a8e258fc0e7b1012048d0ee90961568510c1a7242d6d2ab1573660273"
+ },
+ {
+ "address": "b42341db7912d7e631fcb8508f9f52e3ec1b39e152554bc9690326d9a2ff937f",
+ "content": "115582fc5e1610fc01db14f8ab8bec5889427fd12ad48bbf84ea40f27d60"
+ },
+ {
+ "address": "b437ed9f15cc711c82b9461e83cd28022c97694b67116f5b8d4df7d1b4153420",
+ "content": "41cdd4825925287690d8b1880747a56e6ac228288f703c860f654025eb04"
+ },
+ {
+ "address": "b44b41226dc6b825a4e51c5f2aec0e9c6eb1d2cad6d0db4342306dda91d3817d",
+ "content": "09d46d47833576ea1d3bd2f86e46731c0773a5bc16e6b1d0b3568274592d"
+ },
+ {
+ "address": "b4d997c8d59cb05a2f47754eb63d15daa642d3f49b6f092cb0bf1d1754142c3a",
+ "content": "1e757bd39eb3a33f151144b4b12524750cb0889186658b6f8a7cdfc1c878"
+ },
+ {
+ "address": "b4ddd4a5080e3571bdc93af18fe8b4569bcb44883f258ff00da343666a6f3819",
+ "content": "54b8a59d7feffddf99ec6875de6041f379efe5b804bbb942d824f2f8e889"
+ },
+ {
+ "address": "b4f490407cd3cebe88a49c04bd3c9c137d29750ac65e3ae4a6d5ea680f1e979c",
+ "content": "293c9db0f3a043fc5569c0a94805ded04215d7d0b5bd6d92d0c495451fbe"
+ },
+ {
+ "address": "b67b9d3fd12e16626db483228cfc49a55838ea14d68f7ede8bcfd2fa9a79f424",
+ "content": "34dbe19034199df1d6cf396f23e923b6d58ab50adac5bf20f3501503cf83"
+ },
+ {
+ "address": "b67d9dd7b4e3305ecc5287aa51264017534e52c26662f2834d046903c67e4889",
+ "content": "b40fabbb656cfef0df25d3c2df6e3e8566be503e87195e94a398dcd505d2"
+ },
+ {
+ "address": "b6bb2c2274e5be86419bcaaa7fb8b33ddf44066bf3a2c5c426492862a47c1ae9",
+ "content": "dd6cc279b6274a5547f7e61d12576bb6d651eced0ee987244c21b2805376"
+ },
+ {
+ "address": "b7416be1223d4326c3674894ee962fb4ac0c406541b8f0cb84907ba1a1653697",
+ "content": "428388ce2d012c02e13ede6095b5aa3aef17bb67b22a7d0cdb2b1bf5a37f"
+ },
+ {
+ "address": "b794051f78e48fa9be17258a77a5ccc2f64e0a849c653eed1bb58cab80517726",
+ "content": "bd2c51e3aef950d4663c0618a4dc3caefffc7cb9d09241a2aa637ca72a57"
+ },
+ {
+ "address": "b817c64882a7989b51d1d79672b73e5f2fefbe7be1d96232cecbaa99f55bba4e",
+ "content": "7c10ac2459b71a5ca33b9acaf28cd8d475906d284b34e5fb2b393304a410"
+ },
+ {
+ "address": "b86db4e69a9521f8fb8763d09ba309e75c472248b7e509cfcbaa66f1d4cf7d81",
+ "content": "d09497ef57c7d7d6f8d7e34bc1a998f6eddbf738e1cc0ce73678ae6e06c2"
+ },
+ {
+ "address": "b8886dda0327366cd09a2db4b1e8c579d87a7371c359b0f62363b7a4264657c7",
+ "content": "d663783d95cc7bf5fb40a063dbc922dbde936382f63cc996c6beabdf5345"
+ },
+ {
+ "address": "b899502566506b61105179823b01c5c6be8c2cd9d393f019548da15b2981388e",
+ "content": "09ff204dfd59b587588a390a70b1e26b10bac77d0111056363d8148ded3c"
+ },
+ {
+ "address": "b8cc3ae8eaf4ef783ec0cbdefd626ac92108615014c2ef68f5c5d62d8244044f",
+ "content": "26bd56f302c14fc3b7dd4ac1008897b8b4cbc6464a142c4c61acabfad74b"
+ },
+ {
+ "address": "b8e02b31732c2932897abecbc8933d32e88ccc56fa4c0983ed772c10b6de9407",
+ "content": "d11379dd6dc668099328d482889061970d62899f4178713c6a908ba4fd58"
+ },
+ {
+ "address": "b928dcfb015e88ddea58f81eb047e43da324773b759f3d812a1244e03cfdcc1b",
+ "content": "25920f48fb23498415f413c5e4b37735623a96a43f425e5009ab6d941b11"
+ },
+ {
+ "address": "b94710fdbb5cd19e2eb8c369130756e053224733b6d2388a9df25c0740c4b321",
+ "content": "7b1bacbda4ed45db7411be08aee074580ba68cb7a467ade7c4411a795ece"
+ },
+ {
+ "address": "b960f580bce132ebe48ff2114e427cb6ddb20dc410ef2ea998a67d564827c52e",
+ "content": "452c890fffa283aa3033f2bda4ae5f50dce4f56387eacf7be791455618a3"
+ },
+ {
+ "address": "b967c315fd428941dd0781370e3fdd47786e075f4741f77cf19967f390db952b",
+ "content": "0070d6f724aa67419bea82c1890c5139fbe4561813f5a86510c7b7a7ac7e"
+ },
+ {
+ "address": "b9c1acdb369047f8daa4180c469a2e242b89ac36fe8cdb5bc2869721ecdc6236",
+ "content": "e1e7dbc9262d6ff958b8483cfa973abae166b1ad538454d28e03668539a4"
+ },
+ {
+ "address": "b9c567a15090b0547f7ac5fdf55687db95c80209c9ad26e2a5688d563e4afd0f",
+ "content": "7227162d78ceabe46f216f0d2c16a6194a5ad66bf99996bf60f5ed5e4d9e"
+ },
+ {
+ "address": "ba15b2615424551de3a6a6162cd5f159c92ff66f61cf02bbfcf6c74029404c45",
+ "content": "bdbe1fd82fd138433cff0b4d3583693f18960c18ec2b09d65a2d453286ee"
+ },
+ {
+ "address": "ba2ed321f712aa70789204bdfd197f491b59f9b5b232b03e0dabfbecf941cf3f",
+ "content": "55b13085a23f7c1b9165ca03dd7721b95351c71b814129ea5524edb9d710"
+ },
+ {
+ "address": "baa3d7891cb569010ee8ea9ac34d2abd896e3d4e466cc2d3f3398c005ffd28d8",
+ "content": "2f52aa9532a287a229ca3ec50b2609f4c871130ba0a6733cf32ca9534251"
+ },
+ {
+ "address": "baada8ca61a116f4ac8a12ddccd04552df75bc78fc502a78995ffaa7e73bac9b",
+ "content": "7426360d127bb1425c624315fe99403443e71ac88c55a8f6f63edb2ac921"
+ },
+ {
+ "address": "bab4c7267f012136d05b1e033a2fa89eee6826f3fac8f6832bc2fb35265dc099",
+ "content": "936717944a61dd70f1e045ca3e3058fecd4d844f0212bfa9416bb9e1c059"
+ },
+ {
+ "address": "bb1a8ba22650fb1c57785b1309abb8fb168ccb941b6371fc6c0b086a5a3e5b1a",
+ "content": "6cb49b2f426cbec0986175b300e58bcef9adf01cb6dee819df9ce86bd894"
+ },
+ {
+ "address": "bb1b74a3ce2c17a714774f369fd33bd48c05dbadb0740b8bbe2fce4e4c77b97a",
+ "content": "f5bb7cc7d943a278bbab91a2660ffc42be37c1871ed9295339e27cb69e72"
+ },
+ {
+ "address": "bb7a76a8219e5c535857ba9517f0baca467085efd92989abf804a53272f3a74e",
+ "content": "0c4548c44aca95217fe91d5ffbc011e6f480c60d4a69f8cba4ad6452cbb7"
+ },
+ {
+ "address": "bbdcbb13f92e3afa2fdd82fb1dccab47666cbc18596b49e28c913d8d1793f079",
+ "content": "c396f4d798d4d359a41e1e223598a75c103deddcb3f09fece2e203f2f6fd"
+ },
+ {
+ "address": "bc05785ba1954b3ffba88410c677a654f8713f1a2b43a74fd8c13699f40f70e2",
+ "content": "2e0d54598cc669588f00688fa7b9e6429e2b1c8fb4b8a7c598872346d954"
+ },
+ {
+ "address": "bc21663bbcd74b2ed86f2e4f2792634e8dba45e41853b9dfb671ecf1a35bea82",
+ "content": "511da475af0ff4288e70974fc49742cd25e4b71c43dab49a97a85e77202c"
+ },
+ {
+ "address": "bc3058df745058d84039f52ec141e35b77cebe7dde672c55c1402248c6e526a9",
+ "content": "0dad07e5986cb9a9aa67456b868992518d42707feb90c366dccc7c24ba80"
+ },
+ {
+ "address": "bc4efe0fda1c706ab4a4f2f8f9e509e2c6a77bd26302983fa496ede3b56a8274",
+ "content": "d96dd4883a70ad7c4824d2e4474fa32402f942079ab9b5c437485ce40129"
+ },
+ {
+ "address": "bc9fb7ac57d754e80d310021e826b24e4d535858fc8968a39db3ecccfac0a00d",
+ "content": "554c91709a98a54d7eb7b61889622e4d47e788aeb3ce56144ee10b0e11fa"
+ },
+ {
+ "address": "bcca412953178ccded690c6b7ffcfc0ecd6e846a199159c9a0e8497f9bda5e6f",
+ "content": "78f4dcdd9df0aa7716be8ee988c57c4a7e7dedc9441916f9daaa7960683b"
+ },
+ {
+ "address": "bda5bb45a8e46cd0a9f091a524ddb09f0237a621d436545667acd4538c6fc486",
+ "content": "a12549bbf94f9a1326c3ddbd3bb9ed66b760dd7fe0b5ccb50e28ce6a2c04"
+ },
+ {
+ "address": "bdbc089d095dd79f82ecd6c0e8aada21375a70e01cd56bc1f2b66f8154437e3e",
+ "content": "4e2b74401f2b878828416161b5c5f35f28061e22f3d8d3e45a24bedc7f35"
+ },
+ {
+ "address": "bde54bd75229aced521e46c852669848e93e21759c864f4e3772d8131ad82586",
+ "content": "3e11d3a543643568d2474060b688a4a14dd8fe60f36abd5d25dbb49c4194"
+ },
+ {
+ "address": "bdf831b9fd46588ecd85bd7563732d44430ccf6fce27e81514a00057881bca37",
+ "content": "9301939400dc0020ccd5cc86cceb2451cce2ccdf52ccb4cca1ccc950cc88701b69cc92370cccc642ccfccca24e01cc9dccac427d7422ccd2dc0020cc8e78ccddcca5ccf2cc8175cca259420bccd0ccf2cccecc87cce7cce97accf8ccd341cc900cccd359ccddcce57accf2ccf047cc8fcd6b189401dc0020ccf3ccd3cca8ccb6ccd361ccf90e1f0dccaeccdb683e41cce3707dccbf22cc855fcc8854470fccd6ccdbccceccb8cce80ddc0020162128cce9cca611ccd11163cccb2c1c0bccc475cca2ccf1ccf23dccbe7ccce5cc87cce5ccb1682c4b2739617ecd6b189402dc0020cca1ccee387c3747ccf003cc92cc8642ccb6ccdcccef37ccfcccb5ccc8cc9871ccde7fccddcc84ccebccfc6f6dccd8cc8dccce11dc0020ccf378ccc1546921440acce4ccfaccbe391027ccdbcce6cc9bcc93ccf5612b082ccce1cca635cccdccb2ccd83f2466cd6b1a01"
+ },
+ {
+ "address": "be228dfd5376ec8bcc5ed8fdd47da40a32c1ba1762c8f1eafb3a66d26a84ba61",
+ "content": "967ea1d354b54db148d72de67cd32a0b87fee051f2cda8ef46f94b502939"
+ },
+ {
+ "address": "be51affdc30d8a3bd09f997a3f5edf7dc203b745791a62289a58a769ddb6563b",
+ "content": "0736e5adb1339be4c360b5cfc229ec4b3b907541383a51caab31c394960e"
+ },
+ {
+ "address": "bf332ef76919ded549ee933a798959f3e66de2e0747869ae1a5e5899950fa888",
+ "content": "1dccde557e59ec863e974c91fbdfe93e0cbb1d67169a3d919e3979427898"
+ },
+ {
+ "address": "bf76d9a31fb8d35c69af9429d6e238820e223f0a0af93211defe3585c4d2af91",
+ "content": "e5f1904df496bedf8fd0587a3a26cf35ec9a4f27fe67a2c73799e8cac640"
+ },
+ {
+ "address": "bf9e726d1f93bad43a12726006c9c79b3af286bebe9c3f6410ef025bf81db80f",
+ "content": "9f1448b9d3ee69ba42e82e8d0ea7c19b89473ddee621de82653b3c831df4"
+ },
+ {
+ "address": "bfa941efe07f4f10d34770ee9191a82f40c2bbd3f89c2ee76714c844c0001b90",
+ "content": "6f5d814c1f353d3b4a18d692354de0084dd24ce4791ef631b72bfcf4741d"
+ },
+ {
+ "address": "bfa98ad76f8b2f59189aa8bd17fd95f2b82a77011f00012ea1be5a11954e16fd",
+ "content": "908f2e17a07d894c1df1f4fcdcbb2b18a5488111f8b5ec39a565403c4f54"
+ },
+ {
+ "address": "c00c332f4e1f1476d97c22e4a7a0c18691cd12a6f8d706ed444ef68898339f9c",
+ "content": "1ad766d11bd16e02c792f75d8f41c405beb365fb32be859a784c82583ec5"
+ },
+ {
+ "address": "c018d2e77ed7a86d825ac42296759a9e8779a0d9c1f60bfa373c7853a1abbf3b",
+ "content": "9bd841361e4604e6b91048a2e03818437f0031bbf5369a51b1beffd5fe01"
+ },
+ {
+ "address": "c02ce5632c31963505264c222639a318e6e31984375530c7775ca78a845e0cd2",
+ "content": "ed4b8ae3eef958cd025400bf9a7681ae08233b360b98571cb11dc9ee866f"
+ },
+ {
+ "address": "c0796199cc2d700c94a231647478683db987771a90b9a355a5be13295a3b316b",
+ "content": "296892fe331d28f26024f6030e9a27e266cae63aa3ab44733f703c304421"
+ },
+ {
+ "address": "c09ebb8a2d6bcc7b7e99286584856df5882d5a73341b6f0da20f80577b4a01d1",
+ "content": "bf7ccb49fd909855dab180ccb10c17d75cc433465c6f8bf8d6323965ebea"
+ },
+ {
+ "address": "c0b9f7bcf938fcdfc799da4ceb8cfa2992c10f8900524acb05d1b8e60546bf06",
+ "content": "4173fdb56fbaf9833f8e65216cf5cca55fb0fedf42478a6c6db5a92823fb"
+ },
+ {
+ "address": "c0e5ff29bb445438e1c749d31457412a89bfdfaf1cddb1da36c24cbd7933f583",
+ "content": "4a7673452b851ba3e71a6476042d4af0bcdd72e7e8863d2b906b9fb3ae90"
+ },
+ {
+ "address": "c11eb3b0a31f487a73169153e39a4712f7a377ec8895d3f44c9196b9c632af51",
+ "content": "ad3bd9a41f713921acf0e603ac81aedb2f7a3be98859310966f325b6f6d1"
+ },
+ {
+ "address": "c13e7b0d3d9dc44f961c1a0f4ccf213d02884b0f68aa5e7718af096ab9f42081",
+ "content": "722d54a0dc6189d9a603be0929641a9ed91f316c21870fb460aea4fa7b35"
+ },
+ {
+ "address": "c160f4e946fb5d08c40165b7666b72032e330d9efec65cdb05ce0c0311ff2bc4",
+ "content": "77a8fc528df31071a75a9b8ba494debfcfe3714a8baa7e02075e4d9536c5"
+ },
+ {
+ "address": "c1a281f418284f90a7e622b1e5752fdfaeccb88859fb289c56b6802a7a0751e0",
+ "content": "c1123a32cd383ba9bee86baa5dbcd88720560a0a9ffc5f8e138751e7c5b0"
+ },
+ {
+ "address": "c262d4ee8683c4c2b47942302102141af702e1a9ff664e48c15a52f6914636ac",
+ "content": "303ecd9a387a0a00a8cbb40707fdd524bb21eb10feda5e930fb5277b7a10"
+ },
+ {
+ "address": "c27ebfd25d213286f48df2b27f5200ff45eb0c601eb52258e9621faeb7206a48",
+ "content": "ce605b30297662c3e3c3475ddb44bf1b224847aa446191fce7a0e147f307"
+ },
+ {
+ "address": "c29031f8a5667646b84f1bf062494f601eed7c976d9e51652bee62682930578e",
+ "content": "3dac5ecefc95f8c5f5d5a12b19e37d6032214d1f3e8b4e52f425dbf7825e"
+ },
+ {
+ "address": "c299693bd12dd568512a2cb570dc32fdadb09c2ee64eee9888f6be8c536b97e2",
+ "content": "15eab03775f4d8932cc4937c843e568526f32cc05dde3d76fe7605785ca8"
+ },
+ {
+ "address": "c2da58fcef50624fb31fab57bc63cd233329d77f207d72a4abb3864d7cca884c",
+ "content": "a5aa2401bbfddd6db07f41bd1347e99216d899f7919268550f1fa39099b4"
+ },
+ {
+ "address": "c2f6b48d39027d5af916701347d5efc7325699ae6b149c2aa1a3aef1e36f3280",
+ "content": "7a747328cbf0665e7645eec7487c593a95efae41b1ba104f592f6587f73c"
+ },
+ {
+ "address": "c420095d15be127c3b929bf3f4e86543f47c5498093d86c9ba350d9e1059c28b",
+ "content": "f13578bf40ac9cd404a0a7739690288ee59b71548904043200a4b50ffc42"
+ },
+ {
+ "address": "c489465a499976aa9443017e147d3a3d5bfea59e529e93dc7d1d605e77ad1ee2",
+ "content": "ac8a4e9ab07f08f4f96d9505940090c0a5c2a4cd5fae04f73e06545fdbbf"
+ },
+ {
+ "address": "c50d442aeafeacc9d287f2b40dfb021ef2f506eb335f1133376921abfe6bf509",
+ "content": "fa63502332230464b4cdb2db85c93e006a4e8fbea7ebb0b9df0843978a5f"
+ },
+ {
+ "address": "c5182d697a493d739cfd902626ee9c4ead7bb738e2adfffc40efc6633d8befde",
+ "content": "981427de24fe49c5650d2877607f9b3442a9aa15a38f72fa91d75a204be7"
+ },
+ {
+ "address": "c5406a14745dd499e57a7b217ecfa9940eb6057a66637594cc3522312dc22048",
+ "content": "40eea8058b51c4895496a2a72d8f9324592f1d8da1f89bf3c6de88a5fa53"
+ },
+ {
+ "address": "c569a37c538ed4382efcefa4272ddc9017e4f7f88e25540b4fe12b40d81324da",
+ "content": "a2e3a446ced8b150db80b0f79fe0b6484dcfb8da8280067590cb23f901fe"
+ },
+ {
+ "address": "c575b753fdafb6b7632bc62b6d7071ce2bea84f1282fa2f7b3e7cbc4e6fbda09",
+ "content": "8de98d9af9954fdd2fa11755ce884c79e15eb01d99e7f2f7326e56b4a277"
+ },
+ {
+ "address": "c607aab3ab6a671fb0ddc20ba9484feac1b559236363d898ecf1ef608aa26b0b",
+ "content": "a29f59de756748c7c738a21c27cda34a0a745432e451a50b7d9a1efcf127"
+ },
+ {
+ "address": "c6479ed7b5c71adc221dd112d772f60c80af13ceb371e739ff4b4cc58ea29c03",
+ "content": "e897ccc42761e4131a9008cf8345ac81775ad506cbd106c7058457b12cb6"
+ },
+ {
+ "address": "c6509542a75a40a04a407e4341a8df3202afd32a7cb26e5ad83db6d3854dce8e",
+ "content": "0789f7473725a0be333766bf272eba859455bff968436540dc045aee99f0"
+ },
+ {
+ "address": "c6e8792936a4c4d9445355c8ee375ad4fff0aab2fa382e3dbefc5dbf7fe6e42a",
+ "content": "cefb5b938c025b2db2b7843ba7db1130d83323cced1a16dc61518aa30bc9"
+ },
+ {
+ "address": "c704d9cbb3350c5fa49823a6499e2c7a9b72adf6970c82e85d72523719a2f223",
+ "content": "578fbd374675067cb52b76356d9b5d35a7c1efbea8969f351afe202fe93b"
+ },
+ {
+ "address": "c722e83bdec50bef8238632824b3f9e8c709ec1dd758ca65194e3a43499c3cfe",
+ "content": "f3ad251e1061bc2711b507addf27c5f2abe859c41f8a954c214be01cf117"
+ },
+ {
+ "address": "c72b0bf0012edf8d66afa026ac4897621484477f1cf00586d16959b67f81d238",
+ "content": "0da104fcbb1cb15d7623372ed30de8a77184a80f30adfe5cffa664ca584c"
+ },
+ {
+ "address": "c7635f875070ee76d782d068c0076483d42696f69bbe05472db106da610165ea",
+ "content": "648dbf5346b580cef3c0b334f99559d9a282e990edc592251b12ac24bffc"
+ },
+ {
+ "address": "c7e29ca11dad4d7fb021b79d96792ae75af7e0992b0dcbae09334b9a8d0f455d",
+ "content": "cf2e87e6c66f2e785b909abd8b13c61f07722285a148c08c724f56b503c7"
+ },
+ {
+ "address": "c829ac51c9f5c1c31b985ee2f72ed8b8c0dd6a067c742aee2341b4a1b06d7d11",
+ "content": "0c2e9f00cd0b09ee3a321989726acdb14fa892e1937fb409539e53e000f0"
+ },
+ {
+ "address": "c8abb0d20a9b3ce074139d6b0ce0fe77506eb81d1919b1fd37debbcdcc6fe91c",
+ "content": "8a07a8cc383f214b27cef31b5a8b135eccc1d21a9a11791aa44176b865d1"
+ },
+ {
+ "address": "c915f4ff4c90d36bcde5c02bac2c1f4fbe800b8ff7b9a5f38500d839ac0bd0ef",
+ "content": "069b50c464be645cb23260b42cb10d4167e93119b27a90c35691bb101f4a"
+ },
+ {
+ "address": "c948837751003b68c97e8da73c032b263f110f79e6fa822eecb7a6c68cec90a6",
+ "content": "63bd1f4366cdce81bb4d1479fb93fbfbf3840f79e00a530c45602b192b5d"
+ },
+ {
+ "address": "ca405c22dfd32323f3bfb82bf0c3fd381a98905c10a343884cc14a87d11b9d66",
+ "content": "7defb2fc8904599657367c272abe072223790eb3f16819e75f8df1ac2aa3"
+ },
+ {
+ "address": "ca927e0172991e726998f7e43a33c157d6c1bb0059d1a7d3b081947055a9d782",
+ "content": "12603041fb1760b1ab4f87b2bfae31e4b056776beaae6547773f5f08cdda"
+ },
+ {
+ "address": "cab3b1162d89c7f16b6ffbd2a73a82ad4c2b0121f6dbc2c83a1f06383a020fc0",
+ "content": "cf5c5bbac78b473dfb7676fcc986ddfff3fb68770ca49906c77799ce25f0"
+ },
+ {
+ "address": "caec95d53b8b8fd671ec89253d04e9ad0c2eebf43ed5825dc7fc7d30bd6d956a",
+ "content": "e41dc62a88a19520051d2ec9f64d2644a1ee0f031c1add50fc7ddd9765df"
+ },
+ {
+ "address": "cb25e1043e7e00d523b2cf9bc8f27e65a242c8ac613b59a35dfd0ae0d28a9329",
+ "content": "ea604c3648e19fa1ebbe10415833ff4406e70a4887e9091458e004c4b21d"
+ },
+ {
+ "address": "cb27dc7c08c917081a947a11080b9ee597c0067a347a068e27d9b931ee49e221",
+ "content": "a2943167fffabaf10cf37a328e19fde49f73366e4b0d406c139e87c8bf22"
+ },
+ {
+ "address": "cb37694e1e6c7141b314a1e24be72fb5118f08aefdd8c68d141aafcc1297eaaa",
+ "content": "46b454a77fc2262f2e6fde927a1e0b7a609dd66723bfb63b4a40ed50971e"
+ },
+ {
+ "address": "cb52240e61d45a73560ec64470b31d59ccea0b58e74031cc75ff0d0b1fda36e0",
+ "content": "71cad34c1b89fd9cca24181f42e726348acf71e5563f0cf5c731725988c9"
+ },
+ {
+ "address": "cba274610007f25f312e59b10111b4a5a2911029931913dffae92dd786d3a087",
+ "content": "f57877be945810a173bdb85eb4102e28dc0fc8bcd16039b6871ce8d202b3"
+ },
+ {
+ "address": "cc10b81027c9636b4e27c0617293d0f110097b08b64763a66b063e39f19386b3",
+ "content": "eb445c1de99f83cef72832a402d0c84d58351861b0343e624a9027904e08"
+ },
+ {
+ "address": "cc2f6f7d042100b1e94c59383c5c5aa02752f7c45f29d03a2cdf526002b5c48a",
+ "content": "a50d2a85376a5ed4ebaee13f0c957fac98fea2a9d3008d4d9358c765e086"
+ },
+ {
+ "address": "cc3c57b94f043c14a2f2efa9e685ea6a3441a3bd3374a4cc2c3bda42a069d9a3",
+ "content": "e24b36acfebc4ddd4829f836ec548f7024b2f91414542ee9475f669bdb15"
+ },
+ {
+ "address": "cc76ba88c522f85a4c0827071e51ba14ced883bf57cf8f9e548a48da611a2772",
+ "content": "895c8e4fa102660ff2d23c6d4a9d842c65e2af366309a24f16d1d19b81cc"
+ },
+ {
+ "address": "cc82c783144993c260e7ed1d8f982b35b9c245a684115873d4c74977463444c1",
+ "content": "ca3fe6b10438143c4764f760a76809127078f6681126cf95e23342d986ec"
+ },
+ {
+ "address": "ccb2b4863d01dfe1558eca9f988a24228be5ba895e401462b3e5cb780657d900",
+ "content": "6baf055641ceb61aa4e705c88db41f8d2cd01a6eb4c0478a921c9c3a4437"
+ },
+ {
+ "address": "ccdee40518a75f0165c490aa01b97a99e24fdb5554d206422ef43178ca47b85a",
+ "content": "66d595098604c15ba5099234bb7d3c2fa197781d4c58213e2ad4f5b720e1"
+ },
+ {
+ "address": "cd35d555472b37cc61dec9e8c9625d2ebe2818c035cfd0eb9bc06717bb19bdaa",
+ "content": "25b05339320f30097232d5f60e74ea4665f155012cb5463c6a6d485b942c"
+ },
+ {
+ "address": "cd4e71ccd2811511844ceceaede7a93dd3e21779ac8b30884be8e401a2658ff5",
+ "content": "d1cec43b17920ddf27e3cd69bf39e383da9c3f0d637ceab08df7feacefb6"
+ },
+ {
+ "address": "cdb705da817f4d9b2a9840ff8999a0d319dd946cc030989ee722170684cee4d1",
+ "content": "6be4c84ea3caa75b72e03b5472215cdfe0c7f5e33e29ace61e44d6ce8ee9"
+ },
+ {
+ "address": "ce0ac8edfae37da7b97e186beb713ef33583abbedb6b32af180c0d7292b27923",
+ "content": "e92c451ed36fdcbcaf782a5addfe338575b1b9c17313daf2cc1ce9f7f976"
+ },
+ {
+ "address": "ce51633ecd24fce75318d295a8b543e07c0a501bd6ac38d39c1176acf4072cce",
+ "content": "0e80387cd54ba8e72ccd350fd1e46ed2c13ba745bf932c50e3b49a6ee2ed"
+ },
+ {
+ "address": "ce62ac345e4c5289ba4b55924b395e6c6cca906a1ecfa8b9958147f1c2431dfe",
+ "content": "fb1dcc844f7efdf4d7879a8bc440a71a5033a2025b13069d890e71e900ff"
+ },
+ {
+ "address": "ceba63c3c0891f3853fae95abb48796e73c77340a02eb3d0895092cd263750ae",
+ "content": "3fc875e26792dd1e1808f7e1078ed3aa960f3a562117f842841b9d61006d"
+ },
+ {
+ "address": "cedf19d9bbdb5d5dd9c9917d92c7fd63f2b8c932f5355a7cf42f0f5d62a0b48f",
+ "content": "a7cb39e3f5b2faceb4b87e6584678132f09ddf4ccb73b7dd21cc2cbb073c"
+ },
+ {
+ "address": "cef735ac67a6058eba562245c714846b0e474907627f65ae49293332e351a4b9",
+ "content": "b6477f528720a68026f3c97b23a76493d840d3c943d2a6888f1030e416b0"
+ },
+ {
+ "address": "cefc1b1d690ed4f3224a91434fd5d08d9d0015f4f40574e86bcdea843631cf72",
+ "content": "6ca30c9cf163d9046ca6b4ce8b1fd8586caa22d00741cb96ee851ce1b02f"
+ },
+ {
+ "address": "cf7143900adbb2820a9b1eecd9678fa19d826384ed09c16552b57ea35b32ec71",
+ "content": "ba532ded19e7604471d96aa78f1bfa500adad922d753d7c9d1d017f85ddd"
+ },
+ {
+ "address": "cf7596dd4dd04917c122ed28c4eada52777c040e7e95e575fbe80b17070f0145",
+ "content": "59ea45bb2a436ae1723bb25ff63161617f9d6778692569a7b8bca4c7b9fc"
+ },
+ {
+ "address": "cfa48f2453ba43bde137a9136390aa02ba2bf766c37032cd1e542b10f0a339ff",
+ "content": "eb7ceb0c2a18a94445e752450806175181d865fab8e6604f0dd9a83d0089"
+ },
+ {
+ "address": "cfc6d95e724b82a1309a3a30574057bc6889e0672a7cf76ecbbade0fc59411db",
+ "content": "46a16ee6c5727debe55f4e0882d18531bd9c9a5179c30110d79c5b07c9e9"
+ },
+ {
+ "address": "d05e1f4a0526402a7ae80450a411a5a9dbb1bc041a4aabde814e07010c831929",
+ "content": "473799c8ea3250155cb72fba433fdfacd133532f081f7fbb6bdba5009678"
+ },
+ {
+ "address": "d061cd0f707fbda84f9d59ab23cb00bad85b10a1305effd793bf2376867c6338",
+ "content": "cd06516cf709b920cb731fb2876a6d6428f7d2db7ebc3e4cfefc0891c75c"
+ },
+ {
+ "address": "d0eab940f5a37792b5218d02cbad2ddb95056b670abac5496fa85cb279ccb5e0",
+ "content": "cc743f1860a86de0a38a97216543fc3da4c81f25d69a324b9b0055ff93c4"
+ },
+ {
+ "address": "d0f6dbc378cfbbacf2963fb48db31f1ef63754652a8fe956b6d784a3645e5160",
+ "content": "3c5a85144a784024eb6bb2efdfa11258a9f951e06fae80612c0cde2bba66"
+ },
+ {
+ "address": "d1b50159e68e76283826289117f4e37ac839fdd152e0a7d7774334d620f3516c",
+ "content": "f7e03cab017da32da69d1cd53703f805c42f9adba7c95e606cbb38465956"
+ },
+ {
+ "address": "d23367b44d517c9494c6785c711500b89a84eb93eab80f4c8d57e263d4fbadeb",
+ "content": "dfd1a7065baf2608792a46f5bbe4bb7d8a4f7051b8ac7696686ac62b4c86"
+ },
+ {
+ "address": "d239656a694963863d306dd9ccb78810882292da00967784da130e75961a5d11",
+ "content": "260121fd39a1b4caa887e2156e841263c1e8e7510fe8b74807f083c0be19"
+ },
+ {
+ "address": "d24fc1a782a8e60b6ecd2fee82b80b620ad6fcccfd83c95c0c397b4351db957b",
+ "content": "0ab14e348bd7935cb0705ec315151030f9d2897a1a9a3f8ec2a77d8219e8"
+ },
+ {
+ "address": "d253bc310ef221bc5a296adf0a01593f25291b6b075f77d5e6e95a87cc2261d2",
+ "content": "e77c427e1e7af4ad3088cb91bc4926dd9b4e80409354bfa52d9c8806afd5"
+ },
+ {
+ "address": "d2c9fba43aa5256bcc9c991c3a7e5af3ab13eb98295d3c3f95963871437f2eff",
+ "content": "26b0a46cc0ad4f7cf92df3970f87aa212b894ea235fb8826e92c490bef6c"
+ },
+ {
+ "address": "d30b2f40bda5d7cc6917d247ade7f3ecf8d7d9cbde18bcaaf9929955a21ee547",
+ "content": "3331510b95dc11bd4b9323b18e1bb435346a172f0a203d8158e04cdaa7c9"
+ },
+ {
+ "address": "d3d544abc0715febb5b2c7aa1acd86d471077b7143a39f9c0cc4551ad17db033",
+ "content": "821cd243bf13e82ac0fb4adfa34a59f6f3939e2e3fb733656749cd79662e"
+ },
+ {
+ "address": "d4b729eb189546eaf8c514f0f8b44f356687a229c1642224f87c7ee26708654b",
+ "content": "03a5af87ea0643dd2e326a44aae65c0d68267e2463dd5d57e2149f1beaba"
+ },
+ {
+ "address": "d51735dfd29c91591da8474a3f660fca59815c40a342acee6bae4782e09d61da",
+ "content": "0c3fee444e9ba9142811e80a41cb7e383275c44c166c941999351ffaa89a"
+ },
+ {
+ "address": "d51ab174d7203a32c3ad719a934fdd08a85c8569471d21b45705474c538c0a01",
+ "content": "819c9b4b412d4832782634819b8cae1c48bd4cc308635d6d116253b31843"
+ },
+ {
+ "address": "d586eb2451e2df52b4a1c95088701b6992370cc642fca24e019dac427d7422d2",
+ "content": "08f3a6cc98c3e9c6538f2a621bb63f8ad44f2ab7e8a8035b7d58bd5de6bff438287a54936f842e1b0a350f56376ed678199c8b8b542e86d8f3f5f17b514b95970edc0676fca333ceb06a3e5a61b8d3f1a0015daf532821118944a76beee5ae31a1852444559e446b44c4807de8143a9aa09548728b5dd1a181f7fbeccd7f084141f661be8004b31d98d4ae9e3bfae2f8142a5b99a4218c3165d337a40681b60e01f88a7847234e1ff7c77053036e84619956d9e1ec38fd9c8f5416cfea63678abb7d54c1daa2ad8a5dcba49e633184d09c8c4a48b4c1cbc02bfb8086eedac87fad86c8b283216aafe7117933b62aa85e7faf470056cfce45b33525a9b90c9c969d0c1838a70622bae4e0499e1ce3fc31c5f1aa8633d90cacee1b1854165a818cad5523c49008c80e7061fff4accf6501d02f990618f43c44d91db0fd6150e44dcd6cf5daf5447e00a340dd3b749f3200c666a550cfbd2f5ab71f6f9ab703e5a42055b697f382a920546a7ccc602dcb3ba3b68d34e47a513ec9bb9a10ddf683b8272931d7ff3008bd792f284a1e1ecf8d7a5f8aa6d78b6578f6241ee2b8f135f89c89bdbb2713403a9cd73c14c4bff0eb28634dd38f14fb6507ef80bf115879850e04cf43027aab0473fd3aab20bf02f9f533d22644a01c62847447e58a2de52b6451ee2a2bdd34c46050ece0f01f1da40d50276f58c02fcee78beca32dcb4d4db0e0b76147cbe7a21f9aea46820ffdae1d97c06c92c3c7d4b8d180efa2351fe5cf5619dd867655b50f8324b43e4108d3e8d2c79cbf653d68137c0261c2fb28171dad262006b3f9ece8923013339ec56cb7099048b3470f9a497767161b58bd0e7a17f4987680e1e436262ca05d66224c2b83ecf02a9399a4c4597f6d9b4232044aacffa2f72823653f6780301444a52678e4a40237e91fae08bea26854345d632f6eaecb26e9f837ddeb94ed3ebb3bbfb8c5162a86521c63dc861bd0d664682cd5578cf26e1b10b34623aa27d20371d1db492d596dad9f7c0e88be9f9ce347d7776da45afbb28eefc817eeffdf780902ac293c19b1cc2c89d54b59351b223ef75bbe9912b91e91c2869eb9e8e6527926597ac7e9281c925f5ebb58c43193e333961ff8627e409b8197fde45abb130c41d4bd1f1c4c33bae2708077654facd76bed7ff4c3b7a0b0453ddacf685280a0eebbb28de0a4bc16fc1e74f03d8c0f0068bb55be9e87cb59d578812c074bf8440d1ddba1daeb4a54e0201de88ca08f3eb38b255d8df4e96c59ea938af7aee82a162fd6491c12f87077355a22c2ee11789049261e26b4dc2ad4f70996d6982971bf95c6290fb6c36bf12000fa75324e9cec08a3c11511d137042afc88acdcd083d9773f237390e163e96279297d4261f27283f1fd0dc882f18a5ceb1d8c649461b610ca6521bb6d1241aa38d50f8c370941832214e64882bcda7c3ab48e75acc5952fa27d05a0a6c19b8e36d73933a4d394eef3c86c8019b8b4e2352860b82d2e88614011cf7ae49c4c17b5bf89283508e4ab1c91a35b03dae4b4fc7ac09af99a1560d6532324c86be16e2d452e3b1afedfd0157b7cab2a9b9527d847a542aac7fc75583647182d611df4aa1d620ce3099ae3e41d053a63feda651d98de78378e0912abed549986acac7a2a1a92536c8859c4fe33773b5cb0ad3dfd76f3090f8ba59612862c77d2e8f8982f5d77847d2cafb39b92b3355157509eab6d2b099d2929ef335aff779cbc2b3cb825b6afc1d22a948b62f2a88eaa29d07a12aa9ec3061cbcd0d21cb359732bb580472d7962c2e81b55dd2f7b47c6022c573ae87afdf082290de517392411c5b5aeee200e913ea3e2b68abd731c40bdc616df985f91804992891e895d88ae0a07e3a3f667de9cb34d59cda485384e176e4b8242170d3d094c2f879108c32eff7d7b39cf46fe395d49486177ae637513f3c7c7ccf231cad871a6d2c654d62c464701a742feedb01ef2cc217993c50e39ef0d0753c642438155e4c6fbd255465ab2abd7414edcbacfb4ac20d2a27b878b44c4fcd965ef8244bb5b853f899edbc753b725d74b4ee418b16e6839c7196e4eb589e7c1ddb2b1333a756fc4fd22a0b04d247d9900fceda6c5d7d4ee68a04c692a76c0dcc6ede39ac09c62dac427a48da501c25d58a06b6e3ac1a2cc3a6b89fa15da8168c8ee6c16497e24887bcb96e386ee1f03dd9462a60072f5bfdc92bfde3f1e2c53530816042a9e9ad47eab783e27ee21f07f2ef6e5b44d4c785442d0b8f1d8e784f7510127bfcc162c1695308490ecc32a7a3ef268d1fcfd61e87a97f39340f9454c588da662a579eab0f25cf78091275db5472a0f2a2364e4942796ee970e384d0df031a3d9ba669cd44a638789bf86b20f4fc80ceefeed2090f102787dec9ed8d99db740ccdf6eb627cbd8048d62266de08e926cd21473155ecb6254c2d07d9c45b5f13ab1889e161b27d164ff670b395e3fa54df71c767fd514bdb7c036be5b2dc05cbbd87ae2f23c970d94cad51d62898e84d67c9ab57d6b57b0a905ba21b787634936b1acbd51ff9fc4432d2b6d6e74f7f741082e272ba1112bcc6bed62ee9a013aeed217083d359c10dff1438eeeee51a8cfb5e479427daffe1c1e24a569373356827965f7d117cd539a1f000956a6b6ace8bedb2e432058eb9c094ee954d1ea216e79c23bb79bf9b88e7349cd924af090ece7adaeb75c1dafdb39dddb50edf9e0c0143f8ebf542c45207e539cc8ed6fdbed0b0f8b87ce078c04a6fbef262356a010d1485b01c12d9bcde50f3296b9559fe77519c1b260f6abfa9f36378d0fa8a472035b1faf63b5fe2bfe0d0a34a2be23423ed46c3f93642d2ed651c7d856aa562449d2a966a2945738b36e3bfec2e937a857028bdead69b09654c6944b419cf774da672f27692acb02964c3ce1d919b403437963e3d13c9105812f94b141bf7b54ded7bcaeec90d655dfa77fa9481bb59211ca7cdcb08af55e77cd97141697d6921abd7870e417f2b7e3f73ef254b00bf482123099b1363d1c3917629316fba284a0372d3e4a96600c31b785a244122f2921f31711b338da2138dccb743f516b1f0f71f2ef22dd29b83e6b3ede569114973dba93520b1477833567b0937b47324922861b0fd8efe8e927db2498c1ca3add9270fc510b969d595d0030739fe5bb8629491029a8461431ffd9c2d7459c4fff2fc8e8dadf7347ce932ae07c723be1fa2141820c618655edaad16fe0154bb6792d0179355a4f3054f70ef8518e08e8a47c340d054379a9ad698a0d053cd29a4cf7e6c0b7f450f1671081bd3c71a240dd69978957702bd005ea9959721d3d805b4197f9d5ef93031b1c161b801122e9ccca3248901e54e732193d39f305add9bb8cfbd861f2dabaf90a8253ccdb0c24fe39a71651b096f24f9529b285ad038c51688b629d435a3a56c1cbb989a61a302bddbb72af0a3893d2314765b83bceb81e42da3033dc750221fbc93dd10b79fe0ded0be1f00e1d793babab3afd9aae5e4f973697cfd3479a77117385091cc147b7efefb0fdac52cb0421136681741fea41b8f4773659d53239f6a61d21e7aa8bd39f1b909c0d6f09975c6e92cc252452d1a77685b5993de47a3cabde1b1e8a0bab79302209420881a7bbdb5d6d1468de24a82e7d76b864cd7db0ebea60cc3f1b4055c3fdaa607ad6f7680c64ad16395fe71ccbcb2c902b896b68fa18163232829493cbc57e415822845920697625a8ba9becfc00c3575de36be7dc5300e6ff626a59b268185d57982ac23819eca095dd3c35488c014fcfe788202956728498306dcd79468e72edc0af257e9bd4073794b640171103dcc3f52979497bd02429ae888135b935a90c48fcad25cca1202a1af0ffb3b1089aa6272684c62608c26889b6ae053f0861a182ef33c7f1b80a426ca5a0b3b7b6579a3d656ed993de35ed724c4cf9116aeec1840eccffac753baf832a557660807dd2220e5a35f9dd44f73fb9a4fbee196619078052d3fad467d98cbc3324f8aff1d10ce8150a4737a2c3b1416c5c4946fd20aeac65a56fdc952e94e500b5b59919069c0ccf81433fe5ae15788eba9fe1a3a647eec6d9989393fc3fb493735d7221e58569fe56eb0c23a994dec0c6f0c8d58fcbf616835e65bece2ee347e1aff48d861034354490755c4e999c5bd8cac98f20ca9b4c7e35dc44f6d2dd4130033776c1c11f00dfd35f9d4bc3403f9d36b7936163d35d8ded141d99521d23acb1ea65a09e88dfce8592c5dd80d5df4b3c434e498945cc47948d955e8419319627d5c9f3e55a3c621a23396aec1415d438c1a802c3ba948c274e424ace98920b1f1db9ac4d825fcae8c2cbb0ed46956e417b0e978d98984d8be924d1f73a8882f0c2ad48c730a8d5a2f9542af5c122757edc64a29997ad28fc1e56208989093cb4c093139944ad988d1744aa8170263c844e98b1aa80c9a775c3286bcd75b9c1edf3289063e1d4071cbfb108142f370e187d2e040039de04decefad3d1369e02a567ae2cf456ef13b353e042e55f2cae9af5a2188dfd88a8a407b84c2129052a606ea57fd9c36b65fd98867ff9cacfb1a010cc3801c45dd64976e5d59e163368044e169ad6dc2e9c28fbf29259b0bf4dc562784fa2e82a2b111e2a7d6bc85117ff907a75138408a4368b46e390ed7611aef32b0ad864c01b8287ddb0f804f404d16bc28a9c3727550bafad716a86777ed04a58f1ebc98fe8fb28be8a379a455078b9f869b1d61b9032165abf1abed07f8794b2767ad88525592ad52bafb512bf93401ddc26191b1ebca811c0b67f9bfbd56dab9d2d6118c34123a5869f952cafb8474fefaf47f96a81d7304a4815271573ae3cc2330a8e45e2070166a379db470f93097443b5113a03a410da9bd501efd802e45c13b6bc7d136cb665961cd5dc21c564512eb8068a5831c3d511dfedab9a253043ef80530ad2b562683e98bb44999e04305c2ef2050237d528cf2c04c96943f7d41e2e4ea4d926ebc1e38315f8ff285492078b8e65ebe29caa60e8d3acde753d5153749b4424180d37008d8b4bbd9393619e751a5d26d22a68ac9555f79174e3cce258777784ee8dd8a5437c45d922c12b1751cec063accd1c2110361bf8ea5479e9f789db8eb950a96d4675f9b2c96d2e16bb392dfe02ac56de36c3360c2492f6a9125dcc7403b0181ae9d745bb02977bbc3a7d45127c2514823b6e17ac96fb2d67af65db0db35f2ca4b63045bd6b5c8ae45de693a46dfeb652384625873ef6ecbbcc9d44210377263a2db2d1a3e8f513ee00996921446daf63888a53ba67c4e0cb15178e5e2993d91c9ec3227fdc0cef9341c56d095588a6ab7f8016342524e338d79e321bcfedbc53381fae1a9c83ea890e6fbff14f32733a830860c5a0bbbf55d32f7cc9a0e97a3820a027363dcd0eb361b996ed900accb3de4d1befa714c49f1d10ba6a33261a9592f26c80abdf8892f329446fced29f812b8cded52eac71c135e04f9cf0fdf047eb03475401a80ff4830235192b1fddec282144566dd7a546802d05499d017cd6e56a5151129031a3437a0204e986113a2d7bb708d69524357e939cfa30936e5d3a97966bee9e3a37e60734379d657308b40b6278c03cc4e77112ec4cc3bed29b33717e6fef751f6d18689b744df5559868d76a6aa78cac4a5843a0a6bc53dae4f8a645bee72222607304fd415db7f904d21be8f97137c20af3b03e9ed5454b2957d250944b7f02063ac88dc2874353f2368c5925e6b8ee242c809bf2f95405cfb6f5afa4d93faba8bf3c598ed3ddf598fb7692d6507f124a848d79a792a1f755cd1347c12c190a06e30ea7c49e84f7cbed9ca26ed11915cb73e14d746649c78d0551bbf0bc315aa993f3c18a00689a8a682553d511341c0a8741ea35b43c505f8922c9ef827b4765a22b7b8db5b3a2923f22ab9dbafd6d3b3d942e63d188ff0785834fd32b94b0f758883763cf52ced74c72d85c873b2d9496d2a95f1b26abb3bc7b526ba70764a35fe7d01f9503e5d439d76c6ddfe256e0d00f9085f39b05e8ffcc65d0bdc9dcce2bc5ac1724071a709403c295258c24bfeb94856a461c024461df0c4f4726ecb931604f9d0f8a80fbd3b0fe362d5ca24b6d423fe27461e6533d2740318c0a9685c057b978f72fdb2e2ee6d1473f1e09bcbec2e5310aa601cc45585b780ca85cefaac74538a41f81beb21521859981a6385de48fcd4804b4ea471e9e7f5e04d6f4b55dfe895242d09458fcb6af88c28a658c5bbf23b1840be5843322ccfeccca4d0830cdd8e4069b9a5e6dd27d927b0adce506f214c7ad3679e8341436aabf3bd78f897fcc8d56a625df9914d8887dbc2ed4534235416a3f688e74066ac4dbbd72b6bddba231ecf47f18a949cde296cbfe38bc7f147a20135571e050b9ad5eac016538ab01559db56448a5bba8b46906fe411cd43433adab3dc42d5432c9ab88f9c91680162323bb832da0a4bcdef01519ae42f58207eeacef5581c444b93a569afa595738ec3f7da5fa6b4accf5cca0de526d09b6f5e7ecf693d2a1c5d171348db111310cbd1cee972405a953a7f53a3f4c427e16f379c0daa88c3f40099e75c0cb4480e7f2684b8107fd889d083545f72377f6a14c9a1b575d42e1811a7dd552a9082fa6ca396440003519b6cda92ea344b465122a5b10acdf6a8f21d60c8d8d4ee1aecc8b2b24b96b0b3fae70356a219932991bac1f60508b6b8a2c6bd666f7e8672bd12c07bacdce5a2f36ceeae18c03f99a971750caa807208cf00930ffba0951bd72c30fd0f2136f176fe23c8bb6c182c5b491706b5fbd0f49b383c5e023310cc7c7e93102e00ebc6f5cb35a28aa5fe9d064c43305317a19cc3150d25f16a146b821ed62b428b02c10b0c2fa7c9be0ce580820ee7768a888e655a72a9742db174490369044e1d96f7484ba52c621abdafe63331865631c556d42596cab4886b12afe1bbd9fbeed8fe0f273e2a80c5f02febae49acef34ee45c7f786d8348ed1be7c900ab64e7962ac677f685b1c5e5988be7b8cf1c17d677e8d8177fed9622198dacc3c6f4beef11a79769a058dac2e8dd9f13c883bb9097195c264fefac3e5394a6bfd2bb3344dd861dedc7e8d567ea2dcd67a1ecf8b2a600122e58b1ff4697e267acd2ce322e177f82b7eb58ae264eb229a75f360aec4b0f8f654d0d44433f7c4afb7ad8df170ed70c3b6a5480ee97c648e537dad05f1c42d1ca2fb9b3e83b5548f152a70402508458ebf7a98ff30d2f5d1363ddccd6cbd6c5b1b71db9e40268e0b4719f50adc706503786b67d2970dad279c8192f09b3640eae8ca171d0251b98dd497ea37d1ab3a94f0a71a9d151a9c144c2dcffd23f6d57d551068fd3bbd0b9f05c904eb640b803798f5a14076ffe6ffab0b0bc1bd3566304110fdecf0cf8fe950a5ffa0cf0895bb90ae12bbcb7e2d350bd29d950bf4d3d61380bc031a23c43f1ab5da8237c5e60dded8b05384354cb3d88e7294e4087b912ec6cb6807e0321d938116d83c1709b1d27c7c57fa9e1e65b2915d9683d9f9bf36f83b3c8983dba0e83393e81f2543f32872e72a012db22de460ee619379dea9aa886a0ed7e39869648fb209d827025fc46da957ee095d4cbd0633ab7a602f9f6caa6d9fc83aeb0d9b25a35d4c020333c597fe25a21bea3fd8e20a119ec64e23679b5afdcf5f7296547da4cff7ad5d399ffa7867718f0c3ad9864213c6eea4a27ea12cbf65a6b262f6586fa1f30ad815ad19490629681b1e7b587bee5a17bda3a5cf13cb357cba623b1cedc335e1d499ddc0ba49f0aa68aeddd2d62665c4cd10b0066252520d42d624974b90494a1ef0155d87dd02db83abb8888dc65d0af45a1376e6d5f59fa5a3f56837e96a37f948e57508d1fe41703c9bfa624331240166bfbcb8191f3dec011305e55460f7d872669852221727c48ad422db1cd31accdf9ea708eda6682a8ff182bccdd7ab939875a2fee8937bf9febbe44cb45a979a4aa9d5a3989b0bb15c566a7125c5289a15b89c4656a0fa45e74950fbce1b37026d1939ba1db6dc1d725bcad48a53f24f9012daf8800e033ffa7eaf951145cd5d9a7ce534ddc799854d60909b184f2ebe345b35dbb90138b8b864cf046f3ad1614cda3aa4c0d08a404db37f2d57e0be0479a2ea6e8ebc301824244274c931faf6f4bbdbbc500a621320be53c49e1aa6d0539731fa5df8c04a4b9fa4696f44e7c5e5e57b13e816824a700dcc2ad43aa162c751da8461fb9e8d09d3980b592605016571dfc9b9297826803357e44943a79989b29904925f885c986f4b7ffb5f98f81fef1d61230b555c0192cbff41809d2347fa5c4125503e92d6b4339d1d9a0713b61eceec369d3d060d8819eb307c6b887f7f2649f1634caf762ee0d867586f8182f92127d45302aeaab58a28c8827c884a57568da54e169014eaaef51eeb2414f4617616c78e50cb86db9cf0a6d00a4fbac4a7c076729d0e6c9916cba1182cef05ead7930fc8ac1798171b8a6885020138484fa01aaa2d6c90f6a7d31a0b82c5c6691b79f89dd8432359bebc722af7f58e3e68daab5ed5423ba2f4f0a2fd6b5faef47c2e9120245fcef5cdfff9dac0e9eb1480262402ebfa2f97ad29d506d6cad2e8fa9a71fa9425c4d12ee06808bd1a07b3ab4467bd9935d46242a9dc3b0e79e861b47ed8ed5dcfea9eb7edadd7f7129c235d7157ecade185a5b0e4f0627c3fcebaee8e6bb85b92fee90ea8b8b25a5ebb4b7f2ff92c3f8782e3aa385c42e7cc95f0a287f343322bd2a33f659421eb4ce420b3b452e514e419f9d62e047b6c4dc37686c83a91e44c49f7b16b6db42c608602fd63c9e224373bfb12b050f4f6267c03cf782bfbbbeec1ce079d9d86d81637090dd2657ad3a8186dd353e4ac81b5094508b5f25b5f0dad7fec2e889b6d75dec5510fc9ce5d952db5561e8e0bcc6bcfa28ae5e6fe76b03704bad689a32da5142bc142d96a005f46d435b3c5575d2c038e2b7ff765c3844fde26cdffb43b56003935274b48aaa23e4f9a74fdaa8e126208e81a225e9029b5c77f7e3ae9c40a364dffe250f0118d891e71b9caa7323fd3111d20bca0a582d435da4b45fdaee49869a8438e26019133e84c9453255c67abf6868c2f99578d1d036f3e65dc0ff6243d5819a7e01e9a97f1b370656bc04ce6dd7dbb3c18e057d460e9f29ea0269684a6adf756e478d0bffb3d8c325f07bb40a81db6472250062b648f485b47a4d2037ef77857517994b18aa6580e6ec713bad033286974a46c076616529b4d043ec8b4c532cd53de2922be674fb9978445a5e5ab1bd8b501273428010569cc6a706582283d55febdd1e6b8ecdc70cc36d77de40eea0f74c2ae5df66a8d5675eabd03e9d7b8a4f3bd33701f6427278c73364b8291f5415710192ea36500a968642463508cf2caab0d57d9fbd29964d3b0b91825f036abfdd779a1566e83b6776ced023fa66622e8a3bf57dba0250e9a4371ff862338be327dfdce92739d8863c2f4bbea9216b8eca8382b010bd37447b7f808c9ead104951218c173c3aac3ec41bcaddf92ba6dba93ce1333d3082e9244c2128c2dadd17335583a742903d32a1ddd0424a6c6557f189ecd9ee47df064048a9b8287d827fe377993629dd82cd2298d0b51069093060cc0b91abcc99cdff9d3eb9ea4bda8e18efdb390b22d9d296a4383a789ae3863844cd21718af9610b381655712c2410a922d382ac6548ca31e551905e8a942e927813323abef7ef95ad6c6978cf6fa1633d2d61d6856797c66770727ac1b6018b5cc4f3885d35d85b7da2c36b63ad64f5df12eaef01fa416849b97a0dd2b673abbd32cbbcf4a78eb6f9a616fddf1cdd94222cc0f9e51660a3263fb865e84151ae0d3afa66eacfaa7f14cc1fc8608c41525f3d4bb5ea0866a6b637421f48dca7241790f7e12933f68f6994d8cc8177522372923763bae9d9cdb970a71691b21950633c1a64d5091279bd85b25e758b2e3f461eef34eaf8d120636e963a2ad5a1696b05783617fd0e2db9eebfe4c67ad794f04c3645475393ac118bab01eb552df21b9f12c3bdded92bd29a318edcc4137f75179caadfd772df60de6b2255a80437596e8ab075589d15512277205d174942d5377cb6e9392b59e466575be871b3ab8889a2f557e83afb3750b41170ee7d6e806292bc40d36ea7a2bfc8771fd29022d389535a1bee33c850f35381ec9337e487ca64940302552c57b428051ba5d065bcf71181b7dd7c320a43ddf479577a950c80b1ad55b885ae57cbc644e0c395423d94d1692196a2a65bc230c4ba145227190ebeaae6d9dcfeee9513b653652fa631354b0f181b484729c1b06397ae85fcdea9da6ec5acc81b333735490ba7f99a87b8e2519dd4fa202943098f740b95dc5acc452216e635f4f87f17178b7a9d00e56f883be323f3b982fb9e60479b61e4b6974d47df8e8668a0217d94df780986229dd4eddd496bb1a6fd0cb8347a985e726ffc0755f117fdc4a22d865f9362160b06c2120d6a0524d3e98bb58075554371eefc218c9839938302ebe97b13204178c9e9cda49a4603f80d774b7b9c29ad84e7cdfb4967cbecd050fd8a9352ca311d2c7e16ba0e33d909dd6064bb01ebc7496fd3826852f3998b482e7e32ce6c3300edf002819ac4fe2759bd5e07efc5ea7f5d94920c389dd92ec81b582508f3d3c15126e1f7de2a77b59df952e97ff93b13db03f6ab755abc05a08882d0faf0d168ad216ce27c37e5ca90701fad61f23a95f6f961080058d25b152456b30fad72205a47c097b8f2b71fa87a98a02f1ef810c9ba4c63eb6ec28765ddaa104812e48068d0f94b75007895c1c3a8cc237ac205b5cfa0f6e1fe2bdebe13c8a1a99944914499e839d0f9d6090511434d430ba63d040c893d64d3b06bc715e2ae3852ec83e630363e7fb18e4e95ab9744bd27ccf6aae4a3655d182536e28fa600a492fb6bec19afc86a9a982b21a93120e208f21e2b26d19c2148ce11da64edefcaee5e02ff58c4b97f1aca72f19acccb8cdc8e832f292c9eed4eb329c67492fc086849a2d221ca44cb54dae46ef0fe3600439aec55b8004686205fdc8bf5e42d61670680407ae740a882b85e8df1016482ea36bc1995452af845d7b4306cb063c1dfa13481530f4aa2591b80333252e902606572c99da308b6e71acc05d4e65112d55a68c03f593b211de2f169798449fbe45f68a3705a75a3aae5e729335764f2bdce0dc9d8773e2f65cde844a80bdd62719eda544f54872a41599b6b155e0c2e34f90601ef26474100000a47864c8af6a55aa358a96f33aa07e59b27f566282e7f195e6b9a20a251fc6475a35a6f0eb6d41e2170c88a3c754df663f479a93f9f2d77614898b998211574e353f847e6335c18cc053004c9358c191e4432aadf70adc7c4234ec7a469357c98a9026145e43c813ce339ec822ecbcddd3d9526eef2b614ff27b0811387675b89dc5b42b365c8f59d18688743fe198f2629cd1fa0f59cf719a4b19bb24ea381b080d6291065025a8fa96044ef8e2dbd27e8a3d2acb643dd69589f84da1ee511780b9edd4901ec07dfa344d69efe7e37d63d5f585759e3acba1c2030b917d251494bfc37deb50402a1763eb04ad8a24e3bf8aa533aa3870ff690b476d176cff172009195feab56dad3951102b8b25d731a0e9498e237c707cc99fa0525588e53f113f20da789edaaad97980fc9905c8f18bf063b21c9e586b02b02f10b398c9c17f758c5fcee4c45c91cf5eaf902a9c1ad78246048ff2fd1e3297edeecf287d64e166fd3a19ea4aa7062d9a1d64e68a001f9a3a7c55caef0c91c3c66a58c1a80367cceb7bc15bc2bc404458b62fd506e7041276c5974da303b7c727551abcbe2c328916b723b16451f6a38fd83f165949f73ad8283caa1402589e49952b9245c060e0eeffc84c013a84fa078f5062e1fcf2b4ebe7b05b6b1129ff69d437a6352e1213027841765f158fe46ebf1e55d01947dd17a74d97189fa103c129c3974e03a71489f87ce36782cf950e712a84acbf0c309eea2224d89384082239ec0668319e66726368361593c1acd0c16e55103b5c684a741939abf67892066068f3382333f43e17acd281ca0ac02f0332b218a89dfbbbdeb159d94bad91be8abaa8bea27de3e50f89d2841e8d711e4aeff05e76e49ef77a12f91657eb88cd83139f1df5606cd5961bd5193f3a9b7db005e5c91bd8ad9d4a212bab0dc1a6d04c0802500d5700eaafb558e35792ac5c4f0023ced75479e94faad4174aa3a168ec4516dfe521cb9d8a72dc288dd241508a534cccc2ae3c96c6f12290ebe04375176f40c8f2e623038a294954a80cba5fe9b9aa18e4f1540f3ccbad3600319fbaba262bfc134a248de15431ea6ec367b64be9616d6fcdc3d65cd2003f8fad289a5fac2127163f13d34a7c7bbeb8ec33c0bcb862128947dbe20d9976ee596bd3ac5a1088fa38169978d32cf9548bf0a47daf053ab2818622486b73af5290d24785d7b04e7d7825569d5e3608f3d475188f85845b53fb5b739f0fda874991d5e7183436a5fce366001442d3f46791a729e8f369200575faab2ff38b8fa8b4303838054ab97d11b61888ecd29742a254cbf69316bb0637141a1b97f10216cc938017d3122ae0d64efa0401116154fd84be8ad172976f8b0079db973570fa4e31f293e14c7af516a310032bfcc9fac88a06e5c5651ab6f8b780bd7c25baf28efd479c497cf8f7d705dfc86d4c9a66c48b17f0f4ed3fea1e7af5b5a4528fae28d654e2f49730acb54e9cc4f7959287b59f8cbd6537e0540fcd9f4d1c45ad3b357ce50a54e8f815938c3b49cb4afcc08af176c64e53e6ab5261603384bf154b5b6f16fad7306bb6d65d11f8faae3a1810eb48ac5c73fde519ff7f1f290789a0d9384430aeee1ad5f7a3c44e53ada5218d630767e431f63b7a3820484e565be0c755334e675cba389c884d1b0cdd217e58fdfb956aa56e0cc03e25ef1d372e030abd8864fa8f5881e68e842133b72da53ea6e22ddec8f764a8a8ae1ab72ce686a175d433ef19aaf3a3f4a50004f7beab0b756b6aacb3906eb73447a68692105484c9a8768586151351217ade9906344683952e77ef6e50370889fb58745ae3fdec65f6e0ba0c7933368102c3d2464dd2d0cbd78ba84619c10780768bb817e35e696dad2b8e56e40a1ebdeddb531799c5db5491bd0b29e5af9008c9e06ed20a1bfb1c53b9be55e16a8fee117f529a3929bd987365c5f41c11353495d912e5986148e41ab12db47fb7d0161f9c645c797d5660d9ab13cca1e552a11fc8fe6d4a073210942600b31549cdebf679e161946285dc701577ee7f691f1982f9c30b231b148a5cc585eaeab14004b6baca28b24b78f25c30a5cf5a5e3d4ed5c342296b6fb7c71a2fef3306ccf81ea565d83f7d72d365a37a9559b2ea28682bc2d6d07813175f4ef9704db6068006bdd35154e6174f00292ebba80b417660d382064f6189f0adbd0d48bf65a7f1a493f33d80a85a7d053813d697d76372513211ffefd0b9c2b7bf38d79719bb91bfdad4d27a3ff920a93d8203ee8f1eae549ff1acdbfff18ec325de797ad52c0f7f65942f15976a38527e7899b349bb769fb19dc6628a6b6a6428078ce5eeb51fdf9a3d2828b9de7c814e3e5ca8f5ade7d675c2cbedd7786e95e92a44790e809b5d2695e2195794f0c495738e55e46e32b997c2bea636146595dfd257778f73f99bd641c1926ccc77163420e11b5167d1765a8f586e86c5967c439c9bd94f6511a405afe67a5a870b5aa1ab2efdacbfbbd489512eefb3884cf0f9d48339e7dc109629a965445aff3b33823764641c9884081c674adceda3d99717e2092e93827b18c7d9e4d344ab08ac3e70527197ef90c4b60ea74a422ac0870ed94be847f202d93f11cc5f8406766a5f8863816bd2562732b2897e322fef66b2f2c15b97b1f905887b78ae1ef1bb19dc5b32471c68723c2bb65ad1e9bf1e68d262803b04d8dbb1d28cac7fcebdb2f3dcf292a7c66ca62e58ddeebc59c1d2821349157d4e98dd131b1935416e4491f63befae33422058d7ad59c222aa697eb621e740bf1064fe0ddae4d70587361154217cab55a9bfffa19ee31644dd61fb3318d8c7c027af01fcd9b7f681253b954c4722acc49acd5a24ac5dce27dad128c0e847440adc01df3f851046a8c83425be0b926115c0037c29bbdbfee838643aad6ee2c2e75b9755c28ee39b61e27704f2af4de2f3ae6b87e66bf270c02ff55b0c66c83c6524c9d72759025233a0ed94e35f73f55c2eb5c4a9acb26f6bab512b6b3b9f3bc7bf1c4a7ec6430d2ea632d57bd267c36afee619a9324a5a9332143c54c74f9e21ba5b4911a3005d56b7c3c5fe919a6f70adbb8ff7e41d33876ff2b7e2ed3332d0b252f0aec2a4505a6b0056fc8a4ee8c920a251e5d1a1bd8c141a67a91c6b12ee1ea7aa7ae082d6b53cffc25dd9366662d73e07f2edf3d84c54327d35b0cd2dce703818f06fc2d1014abe233eb95193daee4ae7ea763b1878e223ae6962beb3dc4b4d3169c771fec7a59740f08e4aa099364dd40a7e3030a0865c70858820a9817a4174706b42a681fb5de78aec9cad4f02472c00ed4f07c7a0ce24d1c91a08f590561b9c8a62e053c2afa12493619a856c2f3c81b26ede0c0caa6f7f8be7ab89ceca7de1f6907be7b102858cd94144e1c2b141238614312944794a8a048aba6ed5a36fbd95fddefe165bd6a11a2ee88decf70dd1623326bae5edf73630dd417a0e8c702f06092e3c796bdd6f566e1591f9150fd50d892fed8859f2f064ca9a4d84dab00ce8ca30dff66736bab7fbdf2041b1f3ee2d0c90e3b9b52420958340073d4e0523efa778957dba5d0966b491629b29e4b1e7012e48168849688a2ccc2ce99b17d292dafd7919e38f4032894524ba39bb8c400420410fde65c15f98b6fa3ec9dc2ef16efceaa82a8ca60923b65655487da29dead4a8d27139f239cd7c07d42bf9ea44da914b9a3231bf263a68f507911b96c39a262981ad3492a7eb92ba53c727b27135d444dcc354ad2ed3fb43d9a8655bf6cd531cde0fd75e3b6619b441bc9b8bc73a373de1af68436fa163db2de91fa5b805a971782cb22121928bf47fe70371b0884510bf01db5cde6f44f7c850ea6f75ccd402c0d844697b020821956a89d24f6cd940e27d3e7b92a2c2274b9cf341448925e0904f24b97fb8d644116742becc7b2e0b3175517114e7a78a2a8ad1261b9477f2007d8dda8efee1746dd0615fa528e9b3958b3a2d2c2982306ad998b258da5cf6a96cac3a80cf4c871d3eebde6131456e850e6276caaa3ffa345931ef296fb31efa93bad54dd454ba0607f4b9bbb5b1b06fc2446533b796aa309ee5e3ee259dcc3d5be604072f55faaf8918ccbfbb1b45431767be04f8633affe6c7aff7790bb45cae9f93303988abd76456117e0c6e4ed3cfc594e53812482eca9064274876ebf76852d7f6b033fdfd2801fa5eac788f0f674478dfb9c290dda0f9b71244594136e90866f75faa5fe2107d0bf03e3ad6a3888e080b3b92d2573af6c9eba238c29a7091bc9a873f177d65461bfedf09e5bafd6c8d8ab49531089728437e68e85ada50bc9683ed69eda393c0869f0faf4e0be14513f98e2e1a94c3021531feb40cb60e322216ccfb61e069f736162954ef198bf9d397e0c755c8d436f8143c2f5babf233eeca05fab7934c765de52e662cb601307292e349e992c422e3dadffe74dc45848679701cbe09d8b54959753177f96c0b5f9339970960b1bc1133d102aad5a1dc44345a6319dae32cd28e186af7cc30671ae0a025ae85d9c74ffd5536085c64403df8efc70a1c070cf2a33b4d064ec72b2186660ba35e0a3709abde401e495e5a335bbea68a8215860c49252a66a351172199ccdfb22e79bd7dcea35a3bd6163483507037930874c86a0bdb2466e8576b85f902458310754f7895d2b74d609e7ae404e37486e5bbd3a1fb25dcf9b8bf4a4ad058eac9e585c6c2a9ee51e3d2dbdd6a96c2c926192bad0441ec06a67b0709096ee43b7751737facaf48d909adaded38f48d12868a229e2440f74628a0b84a5e332cdc3e6f74f176c8c2fa4cf241e2bcd1c2860a9991655c8b4ca9bc3f8c5a0b109f7e79a10d76b4dabac39efa681d3abe323ba2a78fc98f64dcda816c4c4f75e203cdd91c4f6693a875a46e88b844143a8ef9382897f24cc841f81e0b70d69413e366f483893acb92bd0cc19da3994966fc62a039685cce7562caf20147dda4ce580be57f40317d3159ba2c4aa7aae655842196b001b3005dce862f081d3dc6cd1c8d92943541f76c265526988c9da14bac5a52ba607eef99d67d16285698e9789373a8698110ae657d0c8d54f6ea1921a35b94c283181e07334cbbb993c53fcadff1a957838fd89996a0a5bac2130b0de8a0a0d8783f595ceca4f113fdaef21085414211a411d26e1dd1d3f7351f716594128ad336ce6838b4dab89ed03da7a40bfa9519f4f22ca84b31c21a50bf9ef4a3282377d942f566cfe947048b24a20c472c7458f5eb719e38a875949a835e01e2a597b2a98673873d5d2fa9e769ca343b9913c790bd8abdb42064f4ec0d0d3f9442986da7fe771f47789ec5a265f6a3587c092453d82dfbe967f980b069942c9aba1911e886335ae6fec29d1929c4228f4b5230a029826d5d849204a3fb7740c8b406f4340418dc5b13f99e8c081a4611f5b166be987593d3f4a2648e16eaa33b837ddf699c391c4f1bd96f502c1835a29772404"
+ },
+ {
+ "address": "d5b5c6988bf23d7e8508f01e82dba6627f3bb49705ac147d5d93d0803c2c8b4b",
+ "content": "b957c5142bb640e65b81e52eebe91fecba09b6df4fd35fa122fb66a56411"
+ },
+ {
+ "address": "d5c625b768dcd0a6c9fa0d7db5327266f94803e00c389896a0abdd5b812c8648",
+ "content": "1ecd28f7cb5c1544591d9ca0acfd5370acab758414b2d5c23ee911d0c621"
+ },
+ {
+ "address": "d5e529d3ecfb3673a2802a2027dcd5775c0b93e9f3478d72abafb0743096f66a",
+ "content": "e47f1e71289e748d80fed4e04d7d02ca86b9b2b7a6ae68f840629abc7571"
+ },
+ {
+ "address": "d5eac03f1171928a75eed1736c260f593d15fc28c6e1bc471ad2a041b3e8e4f8",
+ "content": "938b3989afdb6df8113c1153e1fa149f0e1fe49c07fc9f7ed3bef85d42ba"
+ },
+ {
+ "address": "d665136393932e2c2654b0f9107b9a9df8a300dbfc869ba429b0e011be79cbe8",
+ "content": "eed6f25f17fcd5a09c2bd4501f4747567a89175294cf11241eca98babeeb"
+ },
+ {
+ "address": "d68bab492667d125ed439a9bad67eb47cf801d44666add70e43ad793d1f990c6",
+ "content": "a0edef540fafaad8035e4be7c81059647262f75742cc54a6b8aa2a4fd07a"
+ },
+ {
+ "address": "d69a42befea94848f42aa42b2b65e1a0f6518dd26d26f6ad3e65e1ae75995053",
+ "content": "822e068729224e5892b7ccec5b589a1aa99c08324a3130cafa2b0a1018ae"
+ },
+ {
+ "address": "d716358d836d79ccd44a23324c2ed629518d7214d0ab316a137869e69454d1b0",
+ "content": "19d73d87affc7de75e1963689d326de3c2b680989ff4d445af23a7f761b9"
+ },
+ {
+ "address": "d717b264584124306545495871fc8e23f23ed32d8e59969d724391503d47d7cd",
+ "content": "daf0dbfde1059171041561990515fab373beecfa77955430c427f0d10b37"
+ },
+ {
+ "address": "d7477178ef560ae17f9706e067346d2dc5e9ffc8308073d4bb51e3fd2ddca0b4",
+ "content": "bac2fed881b8831a591b40c7f86d1133d80839619124288cc9e71d554d7d"
+ },
+ {
+ "address": "d7794aecfc577f7a79ecb7cf4cd39b17cb221d485d6aacd3f58dcac633485f49",
+ "content": "80406d73776fe6af3d704b073fb9788c8a875d209f1ef3f10233ed101651"
+ },
+ {
+ "address": "d7a7c792da85dbf72c8db44ed5dfecc82c5476bb92cd82afb260d69644d1a414",
+ "content": "e9560babb6b331383395fe6649dad5613b3a2a442d24990902b417d24364"
+ },
+ {
+ "address": "d7bafeaf48399555ab4afed603adfa2de9ab484f6bccb53b1c0742ef9b708766",
+ "content": "455609e744f539c5e602a0fb59c09661985d0fee0d22ab38b5a1c21ee7ff"
+ },
+ {
+ "address": "d7c857518217df0f9a9fab022da045951e83fe4e7b4fff0b85ddc39010d84add",
+ "content": "12882ba2851090d86546aa2996df625c0517d5b0b7596ae81013644b65de"
+ },
+ {
+ "address": "d7cd9d522443ae3c57f862a6864f0c977d8e83fe2801dbde67c5e2d614b6fae4",
+ "content": "bf1d62c1f85e4acb058495aa5079f0dc663471240801b99df776f7044ea6"
+ },
+ {
+ "address": "d7dc1aa80abf64d752cd5e835a21629ecaa51bd0e72e130c69c4b50857cbf71b",
+ "content": "bccdc0f3daaaaba8cfd97562d91b36dd9e46130e2fa4d0f21d3d208bddd8"
+ },
+ {
+ "address": "d7f8d19472cc3439f23999a072d9125948f87375423010677c8c12c2d4a71a5c",
+ "content": "3b020bdb3c5be7a9cb12634b27a5bb26abf899c96f5bdd6e832c918c7b75"
+ },
+ {
+ "address": "d8210ec2158f87c96213cc90102653dc00b4a5fd5683097370dfc1118554436e",
+ "content": "d34ffeea9bb1577b6da4573a41af53095ae0e0237e9934256e4a6f3d7875"
+ },
+ {
+ "address": "d8244f288614cb225a6455d5e11b89d248b5b9bc04c68a5a07b6d2a72406e2e5",
+ "content": "fe99cde3d9f11da3b514320126d32613ec20bcf75a416921081759f611a0"
+ },
+ {
+ "address": "d824c1c2732d1f83f5c58346956db592345114165416b302c17291d98c79d5c4",
+ "content": "3d65ee27c9b306f258ad763ebab458e8aea203fb5e6817aac91007b3d315"
+ },
+ {
+ "address": "d835b9c619c6c8659f288a79992faa0eaf06141adf8ece7acd023568608a0e44",
+ "content": "932c882d68c8fc0f46ac4c5867cb21177211fcd6a283b70e04781e977a83"
+ },
+ {
+ "address": "d83671078f743865b91ac959d748ea812bd320a6b421d47140244f88e0d56343",
+ "content": "c0871de459e2be1e9bb0d5807db5335e1363696d646d92a740e3a8f1aebf"
+ },
+ {
+ "address": "d85fbda8378dce2ea532466ccf2aacf2b3dcac4603a81c2507db446c7b32a631",
+ "content": "5ea05ee661d9695c1e703147d16089a195070697d69c16f05693d07e010a"
+ },
+ {
+ "address": "d8853168d23950e4565040f439634eaf2bb8e896b486fabb0fb87110e4a41d5d",
+ "content": "477940fb652f9a02f86bf5c8555f6aa86c1ea602974fce484e7ee9547c0c"
+ },
+ {
+ "address": "d8ff8acd981c5512bc030f72b157865a5bb702d7cfd10cfe027186bb2d4e4dd7",
+ "content": "b8bd7c64a432647608146bad8c32b53eccbd75018c235151fecca4814aa5"
+ },
+ {
+ "address": "d940c1c8942cde17bc97ba11bcc29b1576897bbec049de4fa66b45e3ec602176",
+ "content": "2e65af5fe166a3a846d4e3288bf1f45aa3fd0e2f0cc1f8d4ade8ec8d3912"
+ },
+ {
+ "address": "d9c4d572b0c5c2a9d1fab0929eab167ce767feefab2ad1a05907790fab1f63af",
+ "content": "0f8d1dab14dcb9553850e84fca4a5947e3533b73647a6c0bdb9a72ab0fb2"
+ },
+ {
+ "address": "d9f0cbf5e9cd28418ac62cff1101aeea3b735d11dde0afd0385787950395330d",
+ "content": "0800ae3fa49f4b402172309b0585329a8158214df4675f41b27057dae8ee"
+ },
+ {
+ "address": "daaf490b85021526ca34dd919f8d1c912fb0e1421a5a3393b1979c5b56ba512e",
+ "content": "82d56d54d8ee5f962b8488d3502e80307b33e7f6bbf18d1b23498e044ff4"
+ },
+ {
+ "address": "dae9e949ca532359eb6d5b54d69ab2f975ff6ffe9991f6c77322c05346bce4ca",
+ "content": "7db44aaa2abdd2a5bc189a157e806b448229717478361096aa21f17e7a32"
+ },
+ {
+ "address": "dbd41cc228b0a6964140ee7aed1570a691eeb31fab11cb5b0be3a5a0c9b00042",
+ "content": "767859453a212345332f0e897b02cd415b66d636e894e1249d3150fd2ff2"
+ },
+ {
+ "address": "dc61c0abecbc927d92df58c715b4b786003b14b1f9f4b1928e8813ebfcdc447e",
+ "content": "d93797df3b7d40b4c3d76410a4578452580d7b1c23a7b3bb200d546957b0"
+ },
+ {
+ "address": "dcfb3e721ab88c4175792b603dbc1645bcb2751d4ebee67aabeddc2c04369140",
+ "content": "d23dfb2e95e1f7f653efb862d7a1fe6f078a5d409833eee8e0e62f13cb0c"
+ },
+ {
+ "address": "dcfdf657775434f9cb6c6bca66e7d67262ea1fe82a741983759fd56f75598c55",
+ "content": "317b04c137cbc14ff3f53ac4c197d3f4f932d746680b7f9d55d5b548038b"
+ },
+ {
+ "address": "dd0e5df01371bfcb879e1061ce47fc5bcff2f168268b757cade3eea1ea4a4f0f",
+ "content": "a13733ca369a29224806987651cd0e70e5a7b00eefaf799e206d45cf88a7"
+ },
+ {
+ "address": "dd3149fa0f8881219b1d53d21c3717f7a6bd03b0a694a6205821b81c28b362bc",
+ "content": "5028346b2bcc28cd6444fbf0774a8d62194be3e13b8ad959becb540adc7f"
+ },
+ {
+ "address": "dd5a347ef1ac9c5de3de70a2f5e035c324b4c0e3190f8355ef28b7f45382721e",
+ "content": "6244293ffb277bd811c23f264222b81b6d0de7e6b7bc34bb3998b27f8bc6"
+ },
+ {
+ "address": "de389f5294c9e1d9cab3ee3cda4653dfab9f2e47931e741b8ee26b7d1183eca5",
+ "content": "ac9b68fe4d842189ed17404955ec858adb22a6fc4bc9aa093ba39e2c022f"
+ },
+ {
+ "address": "de63ed3419c3d8aa85a4ad3449493c0409bd72d7fee39e023f166b5104a87719",
+ "content": "ec6241be72bb47b3221fe89caf935bc62fb092d49323427263d46e0040d7"
+ },
+ {
+ "address": "deb85dd715e39154c3d5c669219ceffab2a0eb703c5c9a9d9b658aca8b3554a4",
+ "content": "528e253ca47554a545a1029b3f62390e71f07346c496f9f2183033cfec0f"
+ },
+ {
+ "address": "df1880bf2d426c8622d878731a280e33202480a24657b83afd92fbaf19b73cc8",
+ "content": "6c39506081848f4015e9aa7135a27b229d2baa4575a20301f86df8ca6cb1"
+ },
+ {
+ "address": "dfa0e0e1f56381c5326a85cf1f0bd2be6249ae70a176bd964ede8a418289c1a1",
+ "content": "4acf22b550567f7d61214e7876157924087dfca7e6c84c10f0833ea5f6fd"
+ },
+ {
+ "address": "dfaeb22efe1b9680d00f7184f5546abd5bb803d9d011bb424086deaf13bc14af",
+ "content": "fd7e5e97251c1e3028906f4eca3be93f2c099152378ce08fe66b80821fe6"
+ },
+ {
+ "address": "e005abc40c059268023aef7f83cf8d4db415ccef3b66da6d2e136ab3a322cfac",
+ "content": "5ea7c1c4e5c6b6a4fef4a0bd67e742095e87395511157cfc2dec8ae85fce"
+ },
+ {
+ "address": "e05d9d6f2bd02d2fbf6f1f7171c4fc072696d9b33bc54a386bc691f55d4982ab",
+ "content": "d9d7ec9a3c5e6fcdca2e710ea83b524b8023aa8511d9235ee748b8af6c87"
+ },
+ {
+ "address": "e07b9ffc5f0b2a9be633bbcef8027ae82565a317c77ee4e480d60552d90f9a3d",
+ "content": "b619f7234af7e8b8190b7f3b617f16d8e47e10a57de78df89afc62cd1940"
+ },
+ {
+ "address": "e0a6f0addeafa506b9a8e4fcc3abe276271905673c816fa10ea596d77c41ada2",
+ "content": "a250a6e87d650e163cd333b209819e291017c539686ae573f5dc08de0688"
+ },
+ {
+ "address": "e0eb35c4316e44e56d54f83f3684a488e7ad5a21e7401a3324d3f4d07f4a18d6",
+ "content": "95805c12b83ee96e8f0040c8db7ffd75047794cc302336659a7b03508e33"
+ },
+ {
+ "address": "e103687b1f520be75bf6837c1ee81fccf3d8eb14db8d3821a451cc8432ea7355",
+ "content": "bfd837dea74c9d3ab9b66c31aa843a94784c0eb31dac26d9f3dca19eff3b"
+ },
+ {
+ "address": "e136695b3b019b77a8723586484510ecb319cfb7f9885d284535577c264d7a57",
+ "content": "a890893b4abe1b7145e24ff3a4c91859c53c2eaa25964862843d4976ed8c"
+ },
+ {
+ "address": "e14d568723cff3ab6cfebc693aec6d993bef3ddbd1d0689de097b62a71f45402",
+ "content": "a21a60a3cad2c6c495d9a732996d1c00fc74b00d717f14f6fbdacadaa508"
+ },
+ {
+ "address": "e16c909eb28bb0332952c8851ad5a69edf8ea715ef47b96ba19c7de12af1b913",
+ "content": "c138b61d11cc80dbbd026b8df83a2926586182bc717ace4e57f3d09dde96"
+ },
+ {
+ "address": "e17ea31a1f0a71512b82eb74e0507fa4aa8e596da8d53f559187374cd6511fe7",
+ "content": "be3817b71235d16864facd8dee9fb131ec4211d7a5c85f78463ea7f6e927"
+ },
+ {
+ "address": "e189653d1533c2a1adc75c154425c58e17e872f18cf70cb03341478a9ae2865c",
+ "content": "e0381dce663b29e162aa27032537249a148b4f1894f0827e40efb0b46d1e"
+ },
+ {
+ "address": "e19b429254a417451f8a5578911020988c2c64b4ad7d24dfe8a24c0799045fe0",
+ "content": "1f9c02aee24604fc5b68d91275f4b08a88c2dbf92d142d967af1d10d2ef5"
+ },
+ {
+ "address": "e1d156944b13a8d9b5434967bfbdee56e60679ae967918ca1d2248b763338538",
+ "content": "bc593bb38e582dc1650011f38ad2ee2f78f0781e2f25ca024074ae0d7c20"
+ },
+ {
+ "address": "e230139ddb6f3b887b32430beb0d37abcef7bce014275e5609aa5ec3a56af5be",
+ "content": "52966be19075191d0231d06fe60783225394b2709e7d8dc8990828fd996a"
+ },
+ {
+ "address": "e271e9efaad1d8ea37dc3810ceaa2c6cbe1ddbdb497b41db7925e632e7dfafcd",
+ "content": "e1da463356fc2553d12a21d05461177832cb152f308a2306e0ac1026aff8"
+ },
+ {
+ "address": "e2c793c08a01c362cb268db15be13922e6bdbeb8bc95984e536cd0cd33bb8637",
+ "content": "58cae870fa1dfd883e447cab9c7bd410d12c10ef22630cee1de604b77bde"
+ },
+ {
+ "address": "e2ff947e77906cb36a020cdcc605d906d2c751a8f38c40a67a1618d51457ebef",
+ "content": "5d6ad88c6116009412af4584cbc16cac3e3ee3305c04e5323fbbf49a45c2"
+ },
+ {
+ "address": "e33321576468ab325dc4e716ce4b6ae3b7df48c92c90dd43b599cf6481c370b9",
+ "content": "3567e82a0d66e0bcaa33e1f0c6e6439e555c35ac272c3c0044da4637acc2"
+ },
+ {
+ "address": "e3bf6c59547ef9b5c0d03cd97384b5af0a8305461bbe9245df082fcfc21ca948",
+ "content": "e4b225b6a9d12b8884fe8f9b7ab49bf3419ed7d5d14907ea0360b3bf53dd"
+ },
+ {
+ "address": "e3d4639cfdf9f97560c0c48102b14f89d4e2916ef0af68320385371fe747d47f",
+ "content": "feedf553adc136837871220cdfdee8260084935cb767b3580d6067193c8f"
+ },
+ {
+ "address": "e3f6298992a5497b2ceea50aa10bb3e76f3a2223d47157ec79510a0a30370eac",
+ "content": "29961b2b40eba45b269c36fe8be6892b157c01f93d489e2c2fb6e7011922"
+ },
+ {
+ "address": "e40f5c18003aef67b6c0138ae5347ba540dcdaab41a51d1b34224b406ed39cd2",
+ "content": "2d3dd4f71bdfcdf5a5c9054dd566e0db56f59744a6af24d4663bf2df177a"
+ },
+ {
+ "address": "e4b3890b73dc478774ef7469602baf45f2a2a7aa5d877b1df567403a23b5002b",
+ "content": "9a1ea906e3a37c16c89863c2d2295006464dafa335da22c833ea42ec42ed"
+ },
+ {
+ "address": "e4b9fc5246196808210a4b1512057e87117c51b1d4b920447b85e27269de4d9c",
+ "content": "98f144931319764d729eb8c96a4b74f3f798a4f597772d703d0e7ab966d4"
+ },
+ {
+ "address": "e4db5c4125fa47c29017007281feb2917eca8ca47fa4024c1e60e00d0e26f2f6",
+ "content": "746f267103a83bbfed496e6ba5529a86ae2cf74ca69da5aac009fe92b94a"
+ },
+ {
+ "address": "e4e8c662bac88eb7c37bae52c3f56b7eb1f47a9c0dafc95a8a7c521335c157d4",
+ "content": "c37001f9527f78e3115f4b753ef9026ebbc6f7049ed44b94ef2233e07db5"
+ },
+ {
+ "address": "e53c122479fe3f3c13214d96df38fc635267103c9e97ac1a6815f2670ed943fd",
+ "content": "04783ec12fc254fb3975be8d72a902f9843aa6981f3e214573e0e1290cba"
+ },
+ {
+ "address": "e58465e3f0a6af6144a8ade4d4ba0bf63e774fb71f7402b23b62ec1bb4dd6f5b",
+ "content": "ff15f2ee2f1a49e47c5f4db38f3b2e4a29affee76743f7712526bd0e117d"
+ },
+ {
+ "address": "e59f15496be604342a596c66367bbf2803d19c4defff820402693cd20ca70f47",
+ "content": "80673afb469a7ee9d926ff58b1e5f3415cce88576b40bbe2e1a0dba985d1"
+ },
+ {
+ "address": "e5f8699de5f071d9d9b3f41ea91c0444688ad4d09fcaf28cfd77f5539ab95def",
+ "content": "efab610177224081c67c0fa0f9f8fce58777a149f4cf8b56a383a4e699a0"
+ },
+ {
+ "address": "e636b3f681c209913e5865de06f06ed484fce99894f11add3ef404142b76b61f",
+ "content": "6becefe2d00509b61699a61a9fde21a6a72dd39267bd9f6e8814c8e99a01"
+ },
+ {
+ "address": "e64afffae207adf619c2e6b5f1aef9524f5b6312e8628b0f9e5ca496e0e3e38e",
+ "content": "1cb1716c02a08e3174b80738a48fba8d76034e4ebe30f6ecfbe691931be5"
+ },
+ {
+ "address": "e6bef0441363f1fff019738338ab3d4de7c05f8f40eb146196ffd582cff74d27",
+ "content": "4c831edb80c40b11d89772805abb03e6ee902accd1b2afec0e7b14bd61c7"
+ },
+ {
+ "address": "e740ada6bb9aec43fc2b54b82765bac91aa6a28bbf518ec77dad2360a01be0fe",
+ "content": "2196c6257af3ba419e8cef0801b6c7b57f5239a3841f7d394f734b52a84f"
+ },
+ {
+ "address": "e7b3f82e9b429a422694c21c421f6926b75d1d7161d84461416b09076738be2f",
+ "content": "39d17bf50db5634167f81ece1f90cef7c44991001a974e29b3f3c6f99a3f"
+ },
+ {
+ "address": "e7be21fc5559431e8102809e52069dab88427fe314653cfbe3258e916659fc8d",
+ "content": "8be0b0a667f72d7ab41d901864e0a34f5d8253d10beca410242bdf143080"
+ },
+ {
+ "address": "e84f86641fee2c4e5e580d3c710d387429fc23fdf5659564d803ad68502745a9",
+ "content": "3a64e53de54d7c1d244639e9012006308cf47008e4e93bd0f01501d97f59"
+ },
+ {
+ "address": "e8b337e1121ef2ea5733a15d211f67f3314de9866ac0780c6ba406e11b63554d",
+ "content": "c602d91125bb0e03204016bd35f34b0df78bcecfbcf894781a09b69d0cd5"
+ },
+ {
+ "address": "e8c559599a843a81e1a63ef75d5d0b632701086ae0bf6f6d25908d3b80e15899",
+ "content": "a8d27bf711e15efb8c5a5b4c5f3fd8c9a266cd6fbccc2f1874890ad2e997"
+ },
+ {
+ "address": "e8d7eea675b2affe3e440f56254627f50368f29720791fafe081d8bdc1f9ba23",
+ "content": "e36fe2e5adc8c961ba97cc97a784e1e06aec1d2346e91d03814e766dab35"
+ },
+ {
+ "address": "e8fe9889c73e6fb976dbee9df77a30d7ebb33e7cd8c6e1b552c0a4bc60c2ee60",
+ "content": "ef3877193b101c0746c29ae8645e387880eb401c26057f637cf81bd9d6ff"
+ },
+ {
+ "address": "e9e55596e3cb3c01f0c220c64b2816ad83b586747f05269db289c5c1028dedfa",
+ "content": "4978f46df6389199f498a46ec76c1a7a4a9dd09db6536ddfa43f72e71acb"
+ },
+ {
+ "address": "ea12513a1997597ce9c00851460d7818a52c403c1c02ef1f2a3cdd0abd0092e5",
+ "content": "c7f123518af25b8709f343edd01f11a955a38c9be54c0a0f70a447e57e4f"
+ },
+ {
+ "address": "ea1a1267aab4f07733ac190d1eb574956a2ca3f3b261c351e95cbe510c749d6c",
+ "content": "d2f66e5bdaae36de33c60bcff4e02d68c3724f2ce5541347aa02e89003ea"
+ },
+ {
+ "address": "ea1b691d12ec728acbec31104e6f8b17fada2bbc8a558bbc5898efe0127103e2",
+ "content": "59dfdb94c3914b418e816d3222cfbcf145ad57fd4a0ee4e291c6c6816c2e"
+ },
+ {
+ "address": "ea247efb3e21ba0c3cabca99c2899f51701ea88c7b2a48f2d10b53acfb08ba83",
+ "content": "d63a4732018d77a793055a2b5d0d47a1a287b79fa36cd0398e6d20cd23c8"
+ },
+ {
+ "address": "ea533915932f385bb7605e9a381c563c007c2f8446555934ec5d97a3b46cbb0f",
+ "content": "5bb004906d1426a33829cbce2bf229fbaedb9c476191947ba8cd0464aa4e"
+ },
+ {
+ "address": "ea6bbea225846318eb509369f577653fafa9c3940f1dd453faecc3c66e26a0ee",
+ "content": "cf395915abaa7cc7d5c4321b22567cfc27c62c507391105fad2aa7d0f034"
+ },
+ {
+ "address": "ea803d0d522fe6a1092dc9a78640639b068e3eb7e9a85234783923915e8e2669",
+ "content": "cc6de57e52c0339d3a3b9bebc9c7cdfdc27697ff1feda95759ec46e0ca60"
+ },
+ {
+ "address": "eaf6cf9637351a70a9a0824a5bbce0c50e3a73ad39cd7efc84e8597dd1c23759",
+ "content": "7bf69fd5a271c2d151264497922955782e7ecaf66f4feec568fc25b02885"
+ },
+ {
+ "address": "ebf892a46a62d8d7a0262909d55dd1eb7fc4166f880fc429f1d66736c979e056",
+ "content": "1f00f4bdf80ba1975e9cb90a8a09de74ad0abc26d94cd89161a7266d97af"
+ },
+ {
+ "address": "ec2ac80971fcfd91c6f8f9d71e888c38bf0399433cacab7ab624003984608cf1",
+ "content": "1ac970fe3d7644c29981b108d09af621a0a88a07e6fd8cb7b2baaaf09d58"
+ },
+ {
+ "address": "ec4a97d0b08f4e0981f11f46d90de799370d2c7cd268954b4debc90e442e05a5",
+ "content": "88a27878a64872c56bbbb15d33c18be931a778926bad7e3b2b264c210c3f"
+ },
+ {
+ "address": "ec7fb9b02c7dce494506cd3251cd81ae2b4fc2aa95afeacae7ede80b4e693140",
+ "content": "ab857baecfc11b765af88126520ba2502b31c143ba33da6adae1dc9b82f2"
+ },
+ {
+ "address": "ec8e15ff1c5af0e9a12b9450dcc4f1f5e9892a80bcfc60ec19cca869ce8c2faf",
+ "content": "2d2f53564271e6f7a476657d7a5228e578d3f74080d31d0f149dd68d499b"
+ },
+ {
+ "address": "ece21c0a32d8a0cfabbad08fa66b50531c2c1ada1fa7edee0fba757f1b0719f2",
+ "content": "4e81ad5bb7d74d8a7d456ca29f37cc6095ede07d086c5ac2670b3eb80d82"
+ },
+ {
+ "address": "ed06622b1ee8fb1cd5d51e5ed074c4d1918f34000b36c6a922301584c5e92f24",
+ "content": "7fb9e7316ec236f7b096a57e9905240a1b3a157b946d5f672c14dbf9755e"
+ },
+ {
+ "address": "ed68e76d44acbece2ffe61dbcf94bf9d93cb7e87e89a6f4d6397aae26374af49",
+ "content": "93cd1de4cb603fd7406c4588ad4cb90a8709616d74956e3fdca3e4371e73"
+ },
+ {
+ "address": "ed6a4a138f961c9d6793bfac4f99f722d07c4ebb77069af1ba096157ea69d88d",
+ "content": "bb0b7f2e3e31d452eba2e179b28ee747b5ba30cfda47fe4df4dea9a260fe"
+ },
+ {
+ "address": "ee0aab0d6b0ce0a03f97696728c9000e2767189f350373ca0146257697c2b998",
+ "content": "0eaf46fe3af1f0f7fa7fa1323c40d23964de0983ec15a396c8a9bc33920b"
+ },
+ {
+ "address": "ee0ed669e42a02bf05f0d40246270ecac630e161fb58be071b4dc475c0919a1e",
+ "content": "415bd533aa5cfd87529a1ceadfcb691f301ee138145e2930640fa2ebd235"
+ },
+ {
+ "address": "ee5e858c692a1ae2fb28e0300612704cf3248a8f4ece83ae7dd623bcaeff13d3",
+ "content": "b52d613ed8a5d92b36822f22c6992eb04dd73d8e74d1f19d168607f2d1db"
+ },
+ {
+ "address": "ee60dbec95032f7335478c11b6483e4d039601d4ecbf2771cbe6a8dc1509f4ff",
+ "content": "ec1bdf797e77ad92e9678af756b7cc47e1b88eadd536f272380542c4caa3"
+ },
+ {
+ "address": "eebf51094ae5c5b7f1a04347c157ac200c3935ef7de9111dae86b864d5954d30",
+ "content": "767c18479355e359c801ab3dc1958b5ad92b43dd7d87fb471c893d74f4aa"
+ },
+ {
+ "address": "eed296ebe3e9a32116143f3f02810dd393a0d9c63035c184bbd4915d5ac4739e",
+ "content": "2add462b29a55a3185f1cc33f349a9bc43510aebdb2da891e56474d87e36"
+ },
+ {
+ "address": "eed5de366c42428f4a93407ca103e6a71a9b6fcc3ee7ddc6f45f9dee62d76424",
+ "content": "b102cf737a5dbe22395bcbd3005dc9042cbe77354c5a08ba948bde36f3ab"
+ },
+ {
+ "address": "eee4a0878bb173642e7c70b42cf51b0146c6a2550aba4573eaebae5267c1d8ec",
+ "content": "2e597c90efde09fa4af6bf4418a061dd03097e17df97e055a05d93b7c6a6"
+ },
+ {
+ "address": "ef556e598fe28a8eca33923e21c5cad66b3954c301879e5eb78c29ddb9ada079",
+ "content": "43a9fc9252f346283ffc45d0dbbe4bd792bb7d29ec9bec407bcc7f7885d6"
+ },
+ {
+ "address": "ef630adfc775597434138f6f158dec0b3efd303631f2a8a36f792838343f02f8",
+ "content": "55a8ac4765df702063af75f96e2f9798a6edff67d16603931305cad6cbd1"
+ },
+ {
+ "address": "ef6c168044a71a90fc1790cef88198494ac92c10eae85f8a1bd91dd2a24ca12a",
+ "content": "29f4ee503dea541a65174f71fcfe380a91a83ef5e300af24ee1ad3307290"
+ },
+ {
+ "address": "ef8009c62302c4afa28d5ddce195a7225b9c3c53744627dccbf499cb422c6088",
+ "content": "f3de172cd428714cb609d2f81ebb335329002cc5fe0dfaef5fbafa18dc10"
+ },
+ {
+ "address": "efea6be6bc3e5b9675a6196d31c01c557f5cfec17e00e998a144de5115c542fa",
+ "content": "bb13cae33fb6d73b303d61cc1f13b09e5696cea08daeaa13e09dd7cd0a9d"
+ },
+ {
+ "address": "effdd1c12c6b3a2c863737112c9b2965c78b7f8a492145013f031cc75239282d",
+ "content": "79a7c87bcf9632aa6cfced994badbcd2a868b767461d9ee23836608b8454"
+ },
+ {
+ "address": "f00fc99e04cd466e40223077b5ed5d9e44a5db99ca57987a5307178fa4b00170",
+ "content": "98f1816409846c6c7b041717d1bad2ddb7c5a4fa5f045328f4cbd33ed8ba"
+ },
+ {
+ "address": "f025af1bd47d08c18e50127c506e282797d80d55496cce33efd8f3728fb1da22",
+ "content": "054f69999b2104390842877473f752c7eeb210809ab268afe7d1a1ccfcd4"
+ },
+ {
+ "address": "f0461f459af9431e3f879ec1135de4d31d913180388bfc50e256c1932ba02b28",
+ "content": "6fd5b4b451992270f9d34e3f85ac6e0887d4a78773a3f64f682979e80fa8"
+ },
+ {
+ "address": "f04f72ef0bf0551ef7b4aad0bc8bd4a94af9974ca48b5a82d94155e09df5f7c0",
+ "content": "40dcd4994a132e0840d7916ba6bebdf01b44199b7c50b476b8b7c220006d"
+ },
+ {
+ "address": "f0870f93823526735cad8567d1525a17ba3f23141d8b1d5fdc40d6963f2c04b4",
+ "content": "cf13442d940d40f2a9e703fecff3659ed95ddb3226eb92daddf215accce9"
+ },
+ {
+ "address": "f147c864eeb18049a13b12a7cf578713dbc492d1a4a61772e1d9c04ee50f53ec",
+ "content": "c0cfcc6e044705bd3fb4ecfd7794fe28444f1e0f06a6fc82662a82ca57ec"
+ },
+ {
+ "address": "f17b948e017014439adb977a36abf2a020413e8df2eb00572aa97feff8d2d8b1",
+ "content": "c6caf319f3e1d778586531887a7932b54807c2a93c944e1127dac37d1371"
+ },
+ {
+ "address": "f1d40dce28efd6bbd3a51dbf0fd06f4128b3bde4056c3e9da94adca30d4b22a9",
+ "content": "1c412661b3f73d98ef7cff00e1fb0cf2c65436ee7c074ece4d93d40904a0"
+ },
+ {
+ "address": "f1e6e89261d0698cf6249b715c60b798829f3bc8ee9890929b6de2b478738fe2",
+ "content": "89d288553f278630da3ca61c9062635cb26f11260196317c4f1dfa60d3ca"
+ },
+ {
+ "address": "f1ec67c4584d110a55987a1592e5893d7b5162f76cebf3b1b5e814975c6ec6cf",
+ "content": "9ca6eaed175bb5862088312ab4319d378494e93c64a42c69e3c44e3fc53b"
+ },
+ {
+ "address": "f24e07cdccf59acb2eb1b329b49934352866b057dcff632dc0fa185ea746067c",
+ "content": "2f949f528f17d5ff0c916b5d4f403dc8625eba5bf446bbcce286757f9ae7"
+ },
+ {
+ "address": "f250512452ec10ab44272f98a2288243148f9cb98b4b7469dae0d116320a9168",
+ "content": "5131c37f917eae1a3680b21c4972775c51b1226d9a072a86183c47c695dc"
+ },
+ {
+ "address": "f25a1fdd43e0f450b57e187910b4e866eb844edb699f87d9445620ee396a4b7a",
+ "content": "8e541807b450fdf8ca497d6546b48c590a80a39a8af106c6bf4f7980348a"
+ },
+ {
+ "address": "f32f43e16d9932d999e91a4237cfa845ab6bff6d8fb00d7c96a68e44b5c5c1c9",
+ "content": "8182d416325a397d382facd1f840dabfef43ab45fd35a50e431dbcd46d05"
+ },
+ {
+ "address": "f3978e0eede5913f5346d9c894cb01e1ac5cb0756e494774d2b1089089c68c46",
+ "content": "9b4bdeb4a314b603f53b43f541620a7247eb65e8f3377b716195d583a316"
+ },
+ {
+ "address": "f3d3a8b6d361f90e1f0daedb683e41e3707dbf22855f8854470fd6dbceb8e80d",
+ "content": "b194c75b5ee9145b3979d9affa51b1fc2b90406a021a9b6ec27bdae63763cd8cfea3ac09b7bcbf144beffba20026b9047381e4df23f9d7ace1e1c3bde1f02e9003a879e1f5b06a873e7a8f8085410268fbedcc7dee6a524bf832576a9ac2123b601936c5511f4e153ed0f3f983a803e60f0c57285aa9e07b7e481200e1c1abf6cb22f4223e07a6a8f7f27fc7cb38cd656e3fd6209484c61a916af2ce8e82bcdef1965348b9ffb1d72118168416e21dae58a147497e6fc5c7db26deb47b2dadb1b0151a027acd0c5a85ffd6f20b034c8e1d7e88332378b1d7fbf4f783ad3a36ceea2fca7523009fde5b5f9bb177cd7c2aa8982be0b41d0f21d8efa1db81aa34c07e5e15ee785199fb7bdfda5263034d5fc2e82ae1a330dc6129948fe88da180a0618a07fec8bed8c6b3e535083d73154399323d2b0cb0ee6cff90ef8d7dea7d6abbd4eaad85cca134ac7c284eee05a28c909f99cca9747f5a8119f03833744d47057e20e7dc2002b29eafc207179193bd935eec4fdb6549bb7e6d1fe70661152f430ad7ee0c3b098ce6fd0fca4953a89c169e347057ffa67c6dfa57104188de7d3c5ae41af8d93751640cb6b7f922a8e59917687320fc70363c930b2d3aac1a2e41978a30c8ff24e4e58fc95175b6b22c601187cb8ccb05578e0831b942b1e5310097a66f7921fcec59786c6fcedfc78a2cb87f8b9ea78c480da923d9753219eb0de7b5514eebd8007247ffdbcb39b3ff00e18b053f4d1a2536e021cf936ddccda5ccb003f7ccbc7c3b1f05e8c19c052e2dc0014bfaa9f4f00364548b0e2efba6473655c796faf72ae9df0bf159d72fbd542d4ea81efcabbd6f66cd4f13de36d38633e73ff304d66e57494499eb7372304e3b00d469c8eadf293b4568733cbf86f57c0d3575b5dce4b2b866059468f638264f399fe286cb3c1a6eac607e457a80bd066616ab362759473713de8080e60052b5bb07ef9cdea22a6d0b9c90ca89726cb8bbc7784f8d8dba201ce4cd56706495babddcef960beafc57e7567ae77a42ea76fed18838d9b46f36a2596b213d5a045374781cbb65a4e1146d9ca77607d85d96f14dcbed2542b5f45b85d98714e1d7158390c803441f7907d27bfa9b26646a49a538f97869d533685f16f4121461f6d8852a5d8d2661e45d73546580dae557ea2c90d8fb265dcf429e7c70880119a1d4af282302e9cb8f5d0263a0971b4e522cef38c382fb8aa964778599af1cfce63a12ce15c9a2f2bc0a2e7c9e5e063ce85942f2796d19861f90f0c9ab884195a9755a77ccb7851389186bfc7af7f3a5eb932e3eb80b578ee9a81e8ab86b1bcaebb92703e69dcf70ec7cea13c6149609aa09a44bb541244d62f8e2d3610905c264fcface717f7fa230b822d3a42684347664d39f09aa6192ca0b38b11a105e60c6a66cf21dab6d9a7adacd4934b3ea48aeba94fc0425e67ef70d2ed5731823307a7671cf2288a4d25df52ec5a4e18189980eebd7971f95e33129cf4aeacc70cfdfb4d46091ab05823f471bec9b1f5f14c2770afde39f306ef844cb166812d7fedc15bbd85f31144b6140b625beddad05c08e39e6cd6f1316c914094434ad9f5f71387b527cd7c78034e7eab162388663594bd7fdf50486915736bc59e3cbe615b7bf9bafc4a56d57ed1e8a478187ef48c26672d809373e40bb5fbcd58c78fdd8f1388df5db07bb11edeae0c36084663d1e6b9a1b5997d2c1104e0bc6a48e8b496e5f4107a44317acdc76ac19bd854ca4ea2a7772a94ba32852149309a4288052fc1fbd9ef167042264d854eb6a4edf86aa16940d60023d24616a96dffbf02ee3cab5cca94b33186075b6c50618630f67530833d2804de151d0518e79c1a7149d77c3cf603ffe43856a2f974768bfe49974cbce6493c984c746caf42e05ef556cb71a4e8e8d75d13095ff79fd24d4167df83bf07a467f8433d52220d1be362a7a0cf77d79aa09492e8dc4602f5789cb7ecfa835164634c6b51455d4f7577218e6a4675af7c730445c20e3ea55e520cad9ad5790322da2471142e826b7da95b26c03f7610fb894290ad2397fcb2a31717a8a5a5abe6310bad3f29bbfc1c8c2098fc2b684f2cae27cb46eece2788cb925e04624a5d964af75c516b8f564f19a5c6a23e7594dab9b8e96538643d948fc588a9f5714d1e84dfc8e9d47e027baebcc261e70744a86cbea90133ef9d33b21e05d230dac71467cdab6c03b435623f29f8ee6916a40362b774d04fbd286972547d414d0523ab9c388e02451f484eb948dee001d75f76d4fe192e90b934d9f16f3e3bcfd36ccc38b73f9a9211f1f9773609798de5fb20820b5f5027699cfd065942c46c8a66ff081e7d828a05bd5cb8a519f5d0c48c51348316319c06d6ac28d31be6984ad366eeadbff0f864f99706ed9f1dac486cd5a19e1c15c3e2fb97ec1e927f0ae98eb093c5dc122d054324cd3400bb84ef8476dbce3d9a979c05dcafb17cea0f1442904d934089151e5bd9fc4f87239464219ad2c3e6e50b6b9692285c951dff884024cdebdc4983ec9b2793f878274293f51e38ef241b7261fdcda2622dc3229b4eece17113bb76d8bc551eebf2dd045eb355728080c8ed9b046a4d3f4c703ec0351c04a6f41b9e7153340efb93af47f815b86316a2d1baf5349d5596c0b293f5faa41d870e608ae2f51a39ce6337569a48d586eaafef3299d7796d69d365ef05010b6e6b5a94779232110130c541ec5168318ecba0629a65588fcef0424115f38931e7179e17a2a87b6e2364d810bbd6bd5aded68eb9446f47af4d7fc99d9ef1d520f91b4ff84ff30ba5c8467f0838d39dea563308c0c391441745970e54a60082b845355c6aed0ddbceb3ab70f2c6c0c8b29fde62c0d2ab4203afcf90e61c13dc183709bc78e85bdc12d91fd08fd18c5a99940f0c490c9693d8ebad08a5c219e18fe96b0b884792a2cc0fbdc8e4580af6e488443d3e06420008150c69fd0627dd36dd9a966339678aa0a15858ffb9de9f066e4d0035185385d23743b254161958076f6e51dfa0e49c9c566fed64c71b5fcc562826271658f528c3760916910f61ccee460365e60b282f37762e009377a018e59ae149d78c466c5bc2e7ef0dcd5a6551782ea34f8469abd787a8760928fd1840de912a5127d67778163a666a8d01875e8cae544d7dae77e08373f9ad72cf926e0babc89496051f3f684709402d2df4626ad6ab2d6c514eb3318d0b32638fc89c6792e5ff5f29aa9de26aaf2016155d3bb0ea0285ddfb34d96213c15a78a21d9e47034dae9b34e226c8571aea57eb8c90276eb3c76a0f278119d00301b06efdfd4d0fd1b9a5131a0b3062251079cb759b8156cbd2845011c1d1711b0bcc7f9db938da90eeb6b7b5f01910bd7854fb236b93894dbeb91762a2cb07d6b1a1d85da1b97dfea240bc338b3a8a9c0ce2162ee1f08aa814786ddf8c8be4439c3e24aaaacbaab6ca516c945605f42ddaffd013e37134db7802b2134758aea1d10d9f22ba9eb9311020162361af70a4a8fafb7fbd142c823a0a26e5b368f70a0cde7a0a552f8d2ddb30560dadf8f59e93b4ba6c2275d2165a44155e1c28c5e10a5813f32824ef38f7b5a93b8420a9ff6fb86d3965dd16b718d3dcc7a17f0ea2d7fd183ca16467376714ec14808b0ab14e7a13785b68d63d4895ea72f46cbf93cfec93275f187285395d1110eb809f53266b61b5432b8b2707e261ee470db6643576fa6a1ff5a00d7ae6b4b0effae330c050f05a71ab1bdf7bb13c67038278456c6c9950aa806036e6826939fad7fa660c75c6ee4a12930c62eac7e11a91297bb3915b6afe6560d44cccaa4f8a8277a77f2008db643871f5622fca740c996a70503f48e8c464927a6f73384cd77c5cdc89cc50195159faec2dd5be4bd14121af758a4b71cf7162092e723505e3911d59f8f9d4b9bcf6344ab65302c67a02c1c2809a5d11238f6a58533138a489198765fc2cef744edc95605e556494b5e2463f02cffe389fc2c2b2044994791ad36f1601da7994a40bb26b314ecf8482b98e3d564ecf2889ce0c8d9b97c71184716623aed488bb185febc20de5d227250d69af53bcb46234e8cebf376fdb8dbf1d3eeb3523e48af1e8c9136ae1a1e98e2cbf64955e12c86e8e603cd8c245be08315893c56e1910e7cd1998a1c5f8e0aafcf4101cf17bd64036c1c91f18112927d907657f959e68c5e87d9d0983bf1c705a7792542a2f7029a31e6cef3869e7a1b14968bda8bd5e6d2350c49b8f87cc38654943a4de7eccdc356b3d022d065aa8dbb080c407486f598459d8bd2206e3cbd858344beed1d639b7339818a654f78755da5a845d8f33c77d4efc4d970abec95e1695ba95e46f9a21f617d6d6533c3577d0a7fdfc214faef3f2d0df39cde8139e295686ad99237308dcc44db7ba4fb071b0cb86373c30dc9e243b4af2c20eb9d12f08c6dcb9c2736834a32fcc115072ff1d550e84a52066e3fcfa6e6544bc81b293e4e3ee3642cb4f9e95501794517b0dcae4b528d1dd6778e05e246239d76fefd0be7c875f6a3d07c3380f5537522b0539f61017efa842c5c4371a126385162bd8830d1545493b5f19e24922f47e5d81fb4b9a50404bab4141e314b4c4179be75823755aeefaee6a5aa875429eaf66c9e34e8a96c50af2c5a14b8f6633cf131b2253411f2687c26b9e42d731c9e783f09c8778bd4618df1c79eb36336138d51ae13bea528d4a18be0054f50e5c0ba184e996ee356cf3f8ec20e81b7925e8e78e2cd3540dc18911af7f4623ff4b4fbdc5df57ca35b4e364026d7e6cb19fdc9156368efce8b2c62cfacb1b39b0c39c14f4744ecce56a6e2a477ab1995a11864ea207ce575ff98f6a827db73e2f09c253f732eaa599c8071226e3e3aae4aa1a32bbf18cff0c6ac1b3cd809daa3e35594cf43a211eed9ff1ceb558e42b6e5c0a98f56012c0d664c0973893a4d5cf1f28cbda4ab245c1dab654a06e14cd73725807ec853fa2c33d7b2800f02732c036e5aae8bac1d9d80bee764f41bfdc74949bb731ac9b116b2814c71837b4ff1f8fd91df16d66a1abb8aec5aa9883cb3ce2cde28fa39207358e9a3d068f0dc48c232314d55ec7234505e8c1d09f017608973705dfced8308ae45c187d14830bb26e7bbfa0f105cdaf1dc5e77b2b27f373a15a0d320e059d27aaacc7491993d09d4428fdb7cca6aa17810a53fb5b285c2fd7358d6ebf046a04b7c3d7643992482e0f96a8c0993c1eddd7448943901d60d4bebcbf72bceda78d77c90343f956c8f46044fdfe68ccc7550c5349d91b0e08b007f29fa59368add289793d136445b61d369c865b6ca550ed62c682c2d4ef4d0471ffb9e3f48b48c6c120d7ea98a1cd3dce44406a8c66f2053eb85b928c21d112b3272c0f6100edcd3a246667368f19a878fb842e31075c33908ae912a4e428489fbd7d095164cdda790d62d8a2fc29e8ca3c136b02b823a64b1285427a99ec1b3d755b781031b608d99b7b252a2ed66bd2f3d7dee08dd8692d95aa2be03ed5090f806c58d6d5de0fb4d5aeac6b915d12e57d53fe72bf58af370de72c1c188d094846d44e449a3a965be55c17568a1d283f28c03c98f853e73fc30379471eefbc5b9df8bac410dfd9ef0cf3841b011efdaff6642aab949e25731986fb0b2428f4bc68db370b1fd344b84b4bed1ebce4cc6224fbd768fab5b4a204386f9999f522b81db552262be595e49b1330519c75342413aa2157d4488d1499930a61ca6a6be0816caa17782237ca7a13ce3ee24049de716664901fb8c417b00c74a483f34e1a1374d5fa7f41c3d44c25759efc68ac8c5954f88f69b4be66221a97a0afbf2707c282f671d383c4e7e6963333fd63ac031f68f73f5245ffdb1988999e84e21de8b78f00bf2e25296ffc1013355c7031e27f63cec79ccbd913cea472a1a528de7faaff18e6bd00193e9ee77648516460275c8467fb1edbd615c38fc981d35317999edfd5f9f374dcd6071a5716d5d197c1f34bae92bf10246efbb592ea465ce53b1bd33d85c31f09c3e0d95a397b07a6b3be9e542fd5f4f5c96506d6e471786b7a99b0af7532c03d70ea23823c56e4d96add4944f3cef2a9453216eda5d5ebde68a01c8cad6132eeba684eb8442d696d682b83e8de19f5be0dbe5e1a9999cd82912769875d27110da42b95688a4f0ff539587ee914b42a8de02fefc4aa023351c67659c60a90c325a76f74d6efd0cef77329a4a2db2b05234d2509b4c2c6195a6db621976b8cdccb0bd20399568b3e28a2d31d563be1259069cbe5cba297d4d2533cdfbd4cd433fc7b36b0e174dd9e09d03994ca0ca70701d7c40f823dd8ca6b98d2883a7069faddf8f1f5cd38635b6d3d4d105b09ed950c7beb12522fb8591d02971e857dfbcdc3544e882127e7fc0c9d53861a9dd59eb16d58f21899a1f12e339789ec3a60b58e2ca51a068d70cf7925211bb610ba0c4714d030d5f254e47b49e5b6458c085f93aebde596682bf732be4fdb308a0b810c6644cc039fa13c63aa9ba37e0ab3f83caf57518517021660cb24438474912a6fae11ac94a9d3f716cb1c773498fe721a776ae754ac7aafab59372f3080ded3b97813113af532647b4db03b6fee9dc2aafb1904f71a0744c3ac0ce4bdcf89ee14888d306577817aa78aadee833abd5ca30541ed94c1211e97a3a7d5524bd1cae83de2bff755361c928f5d7d4bc2f590536918d64b49df6f83922476e2d5fce6ed5c01c145af5221e45a134d69ba32ce14d6d0e141007bbf4aeb75fd051bb544d6db37f4c8aa500d4a4b20d97e77a266047313cb5d7d66bd4f7c6e2e7dc12db946f705d4ee9ce11efbc8096dada533bbe4abacc472592fb7612bd67ad6f21fe8efa152c1ab086d77eedd1906094771cf17c00943a765e5841f93a84e978c7f6c18a0112755756b667eb93d0d36bd19b4712c550bdcedacee0b670e0486af167150d244621a8927423aecc14f9e5a7c3bbd242fad4398b636c27a328849cda58187b8126d08cc27b906590f315ec20811d8fb24df67d58bbe93b5dbc80efa242da2910f7564b8f951b7150c7f4de171c7b294a18bb4c53798fd0abd875982827a7f78b8d7ac46f04cb3e0cd917c41bb50dbd1bb2ce7ac5a3677d68d44e6f4b6c9817f46e229eaab2d6226dd8199226366e86901d28833aa9a3eb9aa2a0b780386ee4740e5f1f006731d856bdeab049d2947db38bf68a4ee03517862f40741e4ee2fcda507d7b1f6384b5671b649aadde6a29400dcfc5276019b08749a1aeba5b74e190ad970fda67d047b78e8f96239c1136367ca532b968c7072ea78071f7a76f717bc4840ea10effc43071e2a8bf81af7a9faea127b5cdedc83f7134c863ff9bbf9b5bb7231fbd1c06be60e7649ea99b8f4ceb79ed3ef67173dccd3764bbc2265ff15a07450c8273cfd082df628ffe6035f2fed749fdb97c322a6968a7db726dcdaec1b14485ddb18bacfc791f431037767725727e2f6b8aaa18654cc84daac0e517703ec638c5ea749375f53a6d5c4a650effecc7692caa7f291f58b959fde6058ac0f330033351547881e3039d72cc6f9368b0dc21604659aa33db67ed6798185983ba44fada9f3d066be8e75ea609298c6c41586e58f1a7794ba62e848743c8eaaaee3de69d1db213cbd5860cc8e3ee3db576e03bfc1bdc2e89fa7362978877089acb97384cb2874619776d2e56b79fa6b341594f1ea150767a88fd22626d9bb31868ea9014f792ac18d4ae8026e62e16155fd4885de86ecc06e7316654f330820e8f2d15825d3748f0137b0151c1874bdf3995b88635a3b47e20c76559d63cf03e44fa57c4552f3864505c0511cf0531360b33b7d6ee48c933cda67aefb4d710b8e329ffcd2262a1a253b523f6ac132269ab0f5f82d59c04529361defe1fadfbd60cbc22418a342af11fe94272aa9f962317dda68364ec93b96ad909c2a7bd2c8bf33aa5dcceccc5b116780ef5cc8f8b51df627cf1fde4ef385e5f4cfe241e3070ff87369f90a3382637d4dc72a0f0d47a824c2e8b8925b33151693c5bcc24a945fc1b19c97ebbb163d571fa0e1dc829b606be1918c5e4f3d9608de06259bbf256a3cbefe2699537fe4d0afd8eb3df21e04bd0efd533a19e9404f560c5b01338e1075b3a9ba6b076ab2ec6631d0d7d7b3bc0255512ca4b6df445d73bce50e5bc535c451cfece46370f859f8afc137421a36247d02909c03c33d4616b424098174ef752e4f7aff0f7ed702ae0d108d28a2f529c4a0e8bd7ccfbbe6a599af38eefcc4acbf2234c310bab95ee05c850013ce93b362e6ba57774b3175371229627fe4ec8ff40695e2ce6ee1aff2502211e01c6be5ac4a5ca72ef4c5f07a4f6ba507508bdacd49c02165c13112fc29ba154ddd5e195dc66c24640f8340e09a786e51a7977a7ad2840ff8805add7e7bc57e559fea85e0f68e8a2c0adba9aed1f7eb4ccd6b5690f0d712718a8c55b3d3022c96c59ea75b2ec54369a67fdadbdfca4be46412ffc7239c531d281ef2862e76958df88e2ec9d54ffd28955c59ace81bba55ca1cb81d467e40dcc07ba9c3625bf6bb848b0f34fbc67b885d04a7ad2fc921710943f4b7bd49794624b1ae8bdf948aa9231f669919a5d8bb376af3ab78c4338ee1d07d474b47090a488495399cba2ad7de2d55440e0e98f8cbaf35dcab41b5bc6e809b68c566466a93e35f3ee44893b75c718198f6795192c49b1e0a1e5c02d75b832168397de219d7ef11a2db250cea1a5ebbd2176c36a8e119897cabd8afaadd84fb6cfe8fca85e5f8e526461255b2d0277acd6d02efd21457f2a68040ae5c258f3b21128dd0f331f4f8e759c029a8fb93e5496df4bdc6ddd7e0cd496b044ee369d985507023c4167d1c37a4296e9b97904d7948dca9030e7f0a17f5c04dd6ea54c382f8e6d42a3c45515e8366a6ee0386ab0e78ce5675da2258e60893dc8f098636a2da01c545bb651536e2f78cdac0c3cf6f91f935b80ac79c8e917979288b98e4f3e6cc051a83321748ec26ae818624e116ca2fa9e8638fa0f51e22e8b5d1de1c9593ff3f786ad370b08d13d866f7f88ba343ea4f5d4cd2a67079dfb44f801bd7c018c92277f0fc2061273c8053a35ac78fdaad887e08a552c89e695ff684007a1da55a5b11f133b43eb7bdaf872ea8116ee136c6c9a59dfd36a7484587d156638614365e04924f07c0334a7b78692e80491dcfdc1dd08d26ce85160a79f73ddc2bb56b4fa4812c868169e8d6abf1c8014349a2adcc6495b5022297293fb6a8c41cc51356f6b62c377fc6f466a4095fbd847cc085b0975863c28ef0b0834d126a963ac8d1cb54b6e2de0ff5d9e4e24df4e7cabc9dbdb38bbd851c9175c38a0c964300540c12fe45b19eaa16f131cc0088ab54f19c84dda44a7fd0ed671c632314fd0b391b2020798d6fe4b46aa610ea73320df759cf103831c5f386071ac2853be5f55e75f90636fb19ab19e8907bee2d028a10b031c789f1d4230886f3e1486a5f40464de0ef26f97c007bb8523dd47dac0d512f8af017644dbc82f29c0b51e4137d9b2280bd6edbc3827c56d69917fe798a69f06a3531da622a6788eb4bac614eca878da781984f5c35d97d94f630b05df718386403070973f7ddc855983b1a9424a8ab81de30180654f454ae3540f816f4c29e244267d16d5cd08ab9311663ec23fb3d525f6efc61ca777642afd7ca30ebaf02ff2e5a27e6c8a78b2fc1b7b4999e593a43972fa8d4053b4e9c9945e0bb8f52d402ef9124d09994afa81385dc0031fda2bb9966899519a3863f53b7f50c45084b45f2374aa2922f36106ba8b31ca44687fc05dddebd0861961d3f5f3125effbbe538e0b3c4c649b8780f7e2dbbbfdead50a9ba471d86addb8d258c20a254786a1a7d93322dc4ddbc02b42a218adbce829ca62896132f1e0572ae11b7e9489d6a70f061e8ff566faa21a7792f105975d3995901b7b6c26b4956f41be6a437e55ccd3a0864c6484e8ead746a535732daa993779e37d8031d877979d76c2829317d4d6c595ecce56e018877ca4a7a44501db2305bfd29b06d082728772e10b3d15424d913b787603ca96ef19120848dabab78824ca2bd635d396d5a09bb5527680dc909e979ef470ca12865b251a5a17cb948d537e53f7857d01ae1acf6ba10d6cb1b4f723dbed61d2ff97f70a439434676bbb13c40061f8a24c4dd47cecf638d693855b9e95bdc056d08cc34301a1a57dc6dffc9b1fd7aa3e02bcf10a277ec327880ef7d82a4754a6ba9dca0be9db10ba77cb6b8009deb103607c4cee87ae476e39f9ed06aebdb5206b7adaee04016f587e9478bd2834bdc9afd447efdbd02877ee667d73d4b74103db4a6271575cb4b1cb63e82260b1aa71635d73566bbc0d4d8b3eca357cf322fdf1c648fd801926297394ebfdb7dbbf3c655db7f9643e5ea65c8b55574f18ed09ba3b1fe74f264a0ab14cccf1f2825d8ba21024db0af114b8e4e756eef81447c05209e758d3fa98bb133d997158f90e2f70acc0c9f464f5271cc23d1a4461a63aace6064afddf83a3f9916a12f3e17748cd38fb7004988168f99cdfc0f1d9df4ac29386097348273ed873c22e6bf758c013d849dd5057648e80468b04aa2bf7e0102816b4fc4705cfe0df43171377536bc392b577f9c32cea183e3ca33d5160dfd19c4c2c11c46299bcaa45fcdc202447ad0931ee5899bc49deb5563a04085442458bf490383d04c9bac2abcce059f23162aff2d6867702cb86b245c87ef0b891e18e5aae2137ede28d46de87f55b7e68e0f0bafb8b314087225fd27d1168108b4c996c1108a59a93381dc9962fcaec88b09b41c41f10fbb6508e84ea392001c98f0d165e8f3612f6c100379e373c74901e20f93c953e8a14adbaa78ca76cf68a3258962be58954a6ab551569ef8ee4e0d0eaf265429157bf18929fde9ede478998ee3395339798954fecb6389e59e44e7f8f15790f6b1c2d1db204e23166868f3f0b719bae0d931f3c7a8e7e68bf94f98af4d8c87db6f28a1ef1bc5a66f4211bd17d1fac1d9d90089f2bbb9e8624ee8feb9463d874a358263a709a28c0569f615cc036f9af48f38ca74980e4ef7f5b18237bf8e759cffb0f34a162895e8c58360540472f09bf4a94e9c250ea9175e8911e8387f502f40b100825e610eaac59b61c0982994297ab413db2da5ee0c014ff6998e7dd66fbdf2546d422ee76d6a9cd8ca6cd157565050ba38808a38f48a684cdd6ea68d7b32988537068e5aad77ff3da0728fde64712564fc8a490bc5e38f675288492bf288934c2f9c4cee3a89acbaeec3a24568aa3b5529fc8f3531186776effb1d21a1419b4aca796ea7dd5811b760d7ba617fad146c2cd60a7970d284fc5d6103332c45878d6aedafd96c1699c7ce3a8282a78bc1263e7558815689c104f97fe3633d6166aa9be5d9034920b46220e16bb4a06eb62edfb7fedf74bea4ff15e92c5a33111e13120b14aef131cb84e3b2568582a0b1613c7997c802f14beb9ad1b0d113fed72846bf3676ef824d559b562afc05d9e6172da9473f081cec8b1879f0a369c8c4445f4e870884fd17c7a11f026282e388ec66ebfe5a5961f71a925057528463728da24038da6ed2b856b6c3c70d7fc109e0a8adc701c47df5dc21d827f1ef7dbf129f6c34190ad90f906f29407f8e839d3776d77ba6387149a19a252f52291b332a3803de43ad704f66768baa42e09f13f521b3175d48338238edd2e65aa1f97565cd1eb4bdfe4498673edbeea7a6e1e2e31671886b12e10646eb25f80a1ba3e8fb63e87fe39e108e7542a8273527c8d95274a2cdb2f5ce352db7ee9b8d24dab3c63e653ff4ba6fff165a3fde65a66fc5bae4b6c418d3c7b211284b8718da96a0c88ad896da82c6775f5b981230bdc935556d3dbeae03a84785b2e5bcdb200ca332b8931815d6f8877714cd437218e7e53c77c4fae5f941c8d742bd7a8b17c00d41f3671a06d8c7680918acb73146b0e3dd93d78e709cddad953ba8f3342ca8e54559f17545e495186e174539a39d2336678b8bcd96596c45d7a3d0699331fe4514e7fc4198c556055af01238996f847cff42668b01776c8b18a91975291e56c56a2bd5080445ade49503511c13e943f4e6fae53a7524276cdbc59133bd10b5c310460a161443edaf0c06bcab5c719e3e5679ca9d421064991a9054c9977d8be87bc1ee871b476f2646fd4700216069fb88fd10925c1f5cdee4665aa9a01dc1ce637602b1890bc50cdde00681576f3b45aae6479075c5e911bcf4f3105668bcce2d95f926284d6f3a13a186fb678a624addb2176b22de5b923065739db2e48ed0e6a8f58b38411c271545ecf1596918a7a8ee6a22d3fc8ad3ad749aef830cca4e338deb819373fb30f9931cdb28d599ac343e08f84c8418aefb4e252991ecbe0fbeb19f1bd546667f0899d00ceedd155fecc5bce8696ade94128286c1e9dcea8f707c1ceb79fc07e00cb4b1f80bf69f6e5e3643e155617b06ef5e97daab26adfcf1fa041fabec4711724dc4292cd986631ef92d868e128396a95ab92afa9c8f6daa9b61ab2f9e5ecb4bd015ffe3956784feb131c6f787f81285868e267184c3048b98d65893bdef02b65f868b0722649b0946dbe9baf696127f7b17090eaa21df28890f2abe39de7932d0b2f23a5be5507aa20d896da6b5f0397e41db6d2d56fc697c39695b86e1ca16406becd2453f5a12febd4aaed3a9d4f61afbcbd204bd40c3260b85801852ab3b3702831d4806f061c895c96724e10a4bd77c471edf657779bd5b75fa52de2b5186a0fe964c83fce906adb8e84f5ddbfa4504a6e0ed2f376f5ca73c9f9341529a1eff55342fa79b3110664c7d621ff874b362e6fc719b04adc16a65ea4fb58ef1225d048e08ce064a9e878f45bac8c1482caa821f3e49d63f625d3d746befc120c50aacb21857b49dcba84d771702c9f51e12c705d1931718fa9ac4a43f25b2dbf5870495c4529d0f0433baf0f989d325a2ae95a4345b2879a48738262a66891d14476b0256b5d18088e5de4dd6de388ddde90c0c12f063208b584d952809343d344ebf8efea13d93174d724d9cc4d22e108c53d05cd018c94a2863ac298b233e9d340458aa3f95a37ec1f6bd0503726ce316d724e7c38d08e96f06c3a1fbd09d71c1140612b69cb2eec6806377bc63286f63db342c430e2adca6e02cb8050c18931cf30ba6045b2e85cb8c7ade95a0274e70525c06adccc3630d4ce7d26846c409010fb637cdaecb89594fc5d5b6bb022e0e6c36d3a9a886e2f29d78d312505246280884e781dd414e48daf7e217a4b633bd94b6f5ab55a8136dcaad767b493fc416792c79fc7f5bf174ade8c14966f94a825f68574cfb2b124d29b6c1bfe2a054296948f22f5f9d0ba677b4b6e975fbc51aa9dfa07fc94459b3a26ad7dc743f8b2d21a4b6689073feec26b10eebb2b05462f533ef0a3473f6e58a85d9d42cc8c49ee18ca58c10ad820ca49f741bb68dde8ec1b05ef3dcb8fd2f1eb01f4e4fe0ad0c08ee38c5453db12bf4d0e5b1ec0337c66f003ff2a4f1754411dfb45623635de1d99aa4487544bfb313902e3c89af68db749b741148ef8276c8383d4b127753e61ca706dfb2bb50410bd84569f8de2d34a33251c5666b88a31b59487d9c4befe25ecfcf48b0466e305bfa2516cc0ffd4a1cc66e5f17a619fbec7e66307bb8dbf6ba8cba6c52e51cc98e556b9175e9aec6d6360d8977de54cc885e4aee82d82d3f9dc7fdc6341d0e6b43561a14e4237d17d71e1ba57bdb8d2dfdadceb70353904722ec8ebf0e896d998194ac61415d54059d9f23d5f99dcba35c96b3204acabac099901932285754a9ee5dcae71355b4a807f8b0a96ad909fecaf4234a5dfa3ea20cb7af54ac6881ec950935039497d275d3dd6e156e8b0dc9f85d1f6eaaace6df263aab2d7db1529adeae29cef59d88660ae77097f3775c6ce218d806ac319a71ae7793aaf4847b964ec9d5de6acb726e8e042f079915f9f6ba7347f248dd87f077961ed0e22282e8051fafe46e4d941ddb6c6080d9f06ce58d4e38a9f972d4edfe67513ca7fc1ea9304b887aefa1d997d135157a006739bdc879222c7fee25d721914d91fb22b270eea71b4a0ef276549d93e8266e8bc3a65bfebf44b28c9b2f84219d4c8e762f12c14970452397e6a934f442653d13450bdaa37d2ba780cce875cf7a589419ef4e516066dfc5ea5441f9f6f831d449f14478c308cc29e18e127fb78b20776d4d62773b5d6c4f86685044c76bb0767c4d3cdb8c8510ac6d577dd39f6199ca8010a5b79b10a00e2e39ebc8d0adb4eb2bde3a3b71e1a55689e23935cea2ea34c9f79bb4ae225220070df672ecff5f9d18edcb9fc92d4f7d1f41ef7f1a7f51e64463f2d27c8a673f4328f2b62a9045b37cce3389c9f856e6290064eb597f563686d852be93a0517161c5fc6382b406ea9c42eb23d5f4e8514738d48b65fc1001cb363deafaa6c0c99fae515263590b0da0f0f1df76d0b5083118269b95ac2ff2e7c05ad142e1e2e4c21ed9063a80be81eee682fa850e8bc32a7b3571967e8703863de4327a28f447578c32321847bfe4a4203922c632d05676aa6c24af1194618fd4599d45b9082d79ce41c6de649b699ba2ce7c2d13b884ca2aca1404c506c7dda096d321019cb5c6cc53786e735a41a8119f058a2bce94fccd8f11121861c56801c91adda4d5e02850f88c4ece677102dfe28bde6d5dc403d65d52c5dd9bb36e38831f55d5b942e400963bf941f0c2e5bd2c5859b5bd1e4f348048a9afb4f11705937ece71643f9c0f258fd46a67f5870596c5c72e52fdf2820feba616ec48b5c89c694eb6b711010b16c737970c377bae67210556523a11a7cd9986b54606bfac377301246ace6f88e87e2eec6c514fb31882588bdfe674d2398b2b40739d22ffebff04a28dcbdd9fe4a01bae79f1cf846a8c7d4e89251a652ae3a85d83e5e728ab0c77478abe1aefaa037c7fed589732a29c76eaf793e6ccef07cf2f02c6e9f5a3bb791d3a04ef77064824ccc04dd39b6325ad78232668648430d81c0ceec36bb8da2d4857808e9e5664c8289b30cd840e37b3be5a71c4c28481da210fcf5826c2448ef1aa6a33a87d70ea6d53d34edf47362d76517d5d24e381bf13e28ccbb70e3b935dad64d4991063d99ce548aba1d52e9c3f88af3045a2a028f99550a433c7df79e7df01805c174d8a0a8a29b42c6b02de881a9d9164ff7650b1f5a1f4124bf71bbde7ecac4a103380961caed6ed7fc4ed7e6b8c597ddccb51bfcff5c97ea527784f568acd72a32587edcc16445b8b9c375ccba15407bc75085cc3c30ff7a08166a8a4f992b9c2bf9a60f81b846c834a679064f4988631d5b176f297e63aca1d443432f69b980ebde6b3838f0f7ef9d9f07f7b7bc441103eae842bef6416cf8a92df00de27d513faff8797d22a87f9ecf153719930797c27af72f80669172f6a0d32b55b1d6188a1282720a953f2eb8447a8255e91c13ca27302df1c87dc072a2cd24353ff1ddea9e2c3ec5d3ac64d5a55c4235c7a8e9c1709cc0ddf73bd60948e8255e45b26ffa3b2ea4c0fe6c6ad4e0947facd916b6534b771cff1421715e024ed7db47d24df8c9e93129c717d7890f98bdde2db1d9e7dc145bf6e1dbf5a96e7e8557b9d224db2af9de44cdf5a2c8a0e19730de0d98b29e5e32a856c5fef189cef4cc003cfbc3cbdd8c028ce1435fc234d2242301b43302233b4821447a09c43be933a182583d06574cbfe90ca9c3bf6c9df167dfd39bbbdf7300e53c73aaf4d0b53e8ba0d25c9acf057c730604a5676aa5084ccc3650ddffdf2577498985ebdd369ad29bab280e1c31b0ca80ae8b094540f4af8c263c7aba73d5cb59f8ec3975dcc6da4ad9c9070d60187277ad945c7b8e45175cb74a9e6877ce82caa5d59385934d861d256728d9d79279077207a3b93781d19f7f4d45d7c1e0e82f812081f1ad3d022ae1f3278cd28fbc7f984b9aae8c1ec6d045ebf5ba23357f9a71f00b36a0e085ada09cb426f49de6c9d9b3f586d14a88f79a89a3aba4cf840ae4acb943ee5e8e2150dde56711404a0284e9f0799ae8ba1ed501f069dfc0d410c4620591ce16d406ee1fef856d7dbeed9e3c046d139aea77ce92c0ee0bca0c3e56a554d6be6340f98cc0b9a81d4b148fb39416f3fcd3389ea439827d1701cc1d21d157874a40a0a801c895c61e7e85db81d2f8c893c486c2a89fc74bc228b2598080e0f6761be47719864753b2dad41e92d5ca328a00c6103babd362734a2a717ccceefd0db1afc02c876503c0f86975bc854370b2ae2fa48eebaed6782b2963addb5a1383585a1285ba30eea94fb6cae090d631bdc78c3b76b90085acf04376283cf404209c0ef8344e6929fadc084378e8625b9aa543cafcbba31c09372a3e7fda46b3cd49810bdb3aea2bc2341d886d44e746e800eec4a0e7fa21ed5eb0741691e60759271a6c6551bfd9c1e6377c291fbb64ba697cd16785a3ff88961e68a88203578dd65f28631ee7d678e1400ffef8346f56c42925f9fc2f0f8acbf7bf7ef35ea3dddd54ed4c8de40ac270bdd9c338e43102dfe9e1e031a70b58e3bc2614b60c58f4ffa8559d4e475596013742ed92a484c7e0af0ae4addcae7eb72d70811d3f391a055cc40cec0f24187e9e85cd166ef47de4b1acc5e4678c24d91f23a8c39b99c4f04f4372d7d9e03cf0b7aa713524b40b4b571eec664fad285ebc2f2d5fb034d2028388d382ed5e77829479eb482da"
+ },
+ {
+ "address": "f56da415af8090d68a786ed54a4c83a3ba11869b024083a8b691c65956bf9d7e",
+ "content": "6a8690bf207b66a3546ff9b91092a235d3e18240a2eba1fc545a5846e436"
+ },
+ {
+ "address": "f56eeb133b4813d1c3fa729387dae050715ff6abaa67299eceddbabd6911e49d",
+ "content": "355a19813c03315d721ace1aaedb5a4aa11a9caffc102275f80c5b3db013"
+ },
+ {
+ "address": "f5910abd62d3dd49415eb7c61ef72d66108f93171b622622af7fd193ac638fa2",
+ "content": "f24a5bbc6263f8f678870e5bcba74b0ca6596c93e268a824d8809f5a6807"
+ },
+ {
+ "address": "f5ab24bed8efdfd743426bc3274e4259472830206b825bd2a088b767bbbe3c4c",
+ "content": "b328476168e506f840f030b1768b412b8525132d9ea9f9659c64e47990c3"
+ },
+ {
+ "address": "f5b70dbe31a69b1065575268f9c5db0a895c18554bd706c0a8b4edfe82b38499",
+ "content": "77c203943253f5bae78b601fad3ad7b2e167f89fa4657d047124db76712e"
+ },
+ {
+ "address": "f5c9e66b42d4425e781c11444e8af96ecd8b608d582db1206999dde5ce733b97",
+ "content": "0d83c9afd6d210ccd1d4d82fc0827ce46b3cbb919052ab0ae533ef5dc779"
+ },
+ {
+ "address": "f5db6cec271f425b25b8cc94d392b3474c5108608cf698cf3dbf9a4fbc58ba4d",
+ "content": "c857c271578af176f4cd966802ab5028c809ae120182165344263da98294"
+ },
+ {
+ "address": "f5fa1a1112612fc506deefb7cd3b0fe42b9510e9147c139fde4089dc693103b1",
+ "content": "146f714f238b4fcf89424e41e8f88d4e5276c9f218258347de220d378a71"
+ },
+ {
+ "address": "f64b895158abe6614ebf61e0a79c97ae22a1d2754ce92dae317f98736a5c9d69",
+ "content": "f2b375d5b67a81a823aecde1f1f01ffbbe16761137842f8ad9f796380920"
+ },
+ {
+ "address": "f6507be5c219d6bf99f8f449f39a5ec07f472dc896711b4447685f81e47178de",
+ "content": "305069feda6ed021482fa27d40cec121bafd7092ad4f2ee3cd60452b4d37"
+ },
+ {
+ "address": "f66bbeecc328b57f27fa67c1fe0d7d42ed59e9656d68516d9ad9f3c3740ec723",
+ "content": "9acf3ca212772214289eff5b70eda7cad263dad930b48697124d73cef984"
+ },
+ {
+ "address": "f684adce0b460cb086bf38ea0005e6f04fa940bf9ba9042e267465b75c28684b",
+ "content": "ee4d047f43e9ba82dee0cf2b0ed4f3da060b4b9accc2cf5390969e7ec08a"
+ },
+ {
+ "address": "f6b75fb4b85f623b95f79d5a060c6528a4d9f41e16b99158bfba1357fa4e985a",
+ "content": "e80c1a6532ac04d25a31c211101c6d3c83a06f76d6bf07caf07b2bfe4d9b"
+ },
+ {
+ "address": "f6d85f6af946c48094738356d11c2c8eb4edfacc0c17df02bca4f518ef694932",
+ "content": "70838741a09341d293b2154e7c0fd6376f819c0dca818e86bcc75a7e6b85"
+ },
+ {
+ "address": "f70bfdc0d15a8a142518b0ebcc8eac765d465e7ffabafb8ca228a6a2f28d59f4",
+ "content": "287fc4f56d761a91c50b4290e6fb4d8132c23e3240d4b68858f9729fa1f4"
+ },
+ {
+ "address": "f758fa3dae4a7732f145d45877a9693606b2ad7a804b2e3113e411bdb6a38fc9",
+ "content": "859b65df4aca31272388df910c06084d5911c158a2fa7ef486a4738e7f26"
+ },
+ {
+ "address": "f7ba354f74d103ae25e0b5633dd84aee08be10e444e3cc242fa93217de3201cb",
+ "content": "67312b548c96c6187f06f464333397e410e4cfdb2e4ee7697ff70279cc25"
+ },
+ {
+ "address": "f7f30d8b0a54e008bc28c9b1430c9efb40aa3aed8db62d60f319a533dd014395",
+ "content": "9777e892208af0eecb67fd6443e8a88dd94919efc9cb59b8c126fdd53a73"
+ },
+ {
+ "address": "f8128275242102869b7df15e0d31c346f4f7ce3844d67501a99fa3c37a082e76",
+ "content": "56bec8513dc11f7b0bd49f61b52e3c088d51d9d21d230ece02cb4f38af19"
+ },
+ {
+ "address": "f82aff175a0b1a758fc56c002d5ee180f162458a5ad004398fb0584f3da54aa9",
+ "content": "dc2b8e77d76cff0f814de8b1e46237c7b2cedac5e6b03ac0d5c78d4d5b12"
+ },
+ {
+ "address": "f88752b660355c77dc2772eb6c4074bf1a63cd10ff1b040af7c2711622706526",
+ "content": "4a1f35a28d7f767b4c6081d3bb4ff39c07c1f6e0d2aa7bdcdf20ce3b59cb"
+ },
+ {
+ "address": "f88ed6e1d8c01360849a11df03bd6bb18145221be1f6b8566bb2f70086f14e06",
+ "content": "31b92009400b45f7aab004b0575b21b96a7a66a5e6dbb75a20d69379e380"
+ },
+ {
+ "address": "f95dff9dc17faf81fcbe2385f582ca3bc785c4522148b8237d3ff86350ea0a00",
+ "content": "a5321cab7274824681191b6f57d592e972000d9227c5f1a6ef3cac280c0f"
+ },
+ {
+ "address": "f9a50683d9c92470afce3c5b19f0d2b142eb85c67b003bd414c740a82014beed",
+ "content": "5577f21872788bc51fdb01a989bea23e655ffff36097f29a0d5aef846c7d"
+ },
+ {
+ "address": "f9fc334744f619e99d08d2e23f9a9ec747fc36e0f26ac528d3de27bb0253d277",
+ "content": "e2d54a9ccae8ca83842cb79c10d60b91d5fc57b5072b049ffd2e41f083b6"
+ },
+ {
+ "address": "fa11ea7ddd492d3c92fc6baafdda2f4437a0f429c2858758a8e346a4bc491346",
+ "content": "821abd7c3798ba92e67c756b6beb4da4c519256249a7b0da605f9062f1b8"
+ },
+ {
+ "address": "fa422e96cd0863d53e591e5083519a80b990db536f42621299d784c4675604d8",
+ "content": "b936de99559441dd8ec02257ac6887e8e1276e5987d333811b71a6cc731a"
+ },
+ {
+ "address": "fa521998f449d4c13d41eaa2d1fb3dab45b3598074528e50d62090c2e6e99f90",
+ "content": "8dd999dce4979549ec4391320d11e4bd74b5421887983a05e69dca778924"
+ },
+ {
+ "address": "fae8415937941cf2648a05f5bddf9bfc4f6373efa409a8709e31cba7d7583973",
+ "content": "9974f585107228b8b2c762cc3a02706a4edf2815eedb2c4b40f2bafaca77"
+ },
+ {
+ "address": "fb1fec2943c343651d97b338b0d2809c120a0f0603cf2a8b18eaf2472f4f6cfc",
+ "content": "5a7367305ad238c4f82ed5ec7089bc4d5dfb09e1d77a46586ac5795e155c"
+ },
+ {
+ "address": "fb35e7221b609320bc2f7b251cb7112d548b15eab6eab863d0126bfb4390a482",
+ "content": "9f998aed63d2c6d27d31cd9556d373afadcdf5442b6df6eb67a6e9aebfe3"
+ },
+ {
+ "address": "fb84cff2740a404b4d76470eebd8b71732c1a14a25132b90baaa613be9ebf29a",
+ "content": "51376f586e757437d948d5172f46181dda32a0deb2bc32b4abbce2e10331"
+ },
+ {
+ "address": "fbc007d07c63ca3ef940dd629a1998e31c8a0900877cbdbd9c785a464ed97a5f",
+ "content": "f08509d7efcbd2c2a40305398bff62d8b2199d02d2239f23d724aeb700a6"
+ },
+ {
+ "address": "fc3117f4c66240f2cd2973bf458ed7dec29b291b2d77fc3a2d7765d15f2a005f",
+ "content": "b9d5d36b4c025c02199b551362bd18e851d0f702c6198e15d4b2d8f5c9ad"
+ },
+ {
+ "address": "fc446e57242b8cce3d487447b32cc54bea8a717b520605bad0ff51d400889be2",
+ "content": "ffbaa686fbd196d06a24e210dc3ab166ec2f64021f28256d6198bdb1ca48"
+ },
+ {
+ "address": "fd0a6fd4a40d26705814ccafddfe41c28ab5467785c474a5f78a6eb819230637",
+ "content": "f868f8b86942f8a38b8ac608f665fe52edef8ed2132f556a934dc4171467"
+ },
+ {
+ "address": "fd12ee41c753d85ee58e0c61e5d27b12321545a07960deb3da3af57c4719ce58",
+ "content": "2c368b36f09de663d54de02a78702e0fc56048474ba0c6fa5da555286abe"
+ },
+ {
+ "address": "fd20fd7cdeb10e62b4ca44ccc6598374876c237e1476c1a57a45d93d62d6f7c7",
+ "content": "a05cdad85f62918cae68d59fd9c11dfa043e010a486bb855a92d3eed8e2c"
+ },
+ {
+ "address": "fd610df775c0b229ccc76d1777a51c2f5a022fbb88def3f49dac8888beba7a4f",
+ "content": "48a3171e0ecd4c23845ce5c36840d8064bf033ba7fe6a14b927d054f6859"
+ },
+ {
+ "address": "fd613b466d3dfa826cd26c739542866cce62834815747a9b4cd10063b6a360e2",
+ "content": "cf9b453f4c43d83704ab8a68fd34898d2e88caea31c900efc518aa110862"
+ },
+ {
+ "address": "fd6e9fa58b0c0fc77f98a0214338e55b22a948a2c94287e1d8966458e54ca688",
+ "content": "952b5846261158f5bb42f719e2711f51a23d1cf59b124e64320f3840c2ab"
+ },
+ {
+ "address": "fda305bfbd2e90750a40bea424e47a21bdafa32005d48a3734a20250b193e8fc",
+ "content": "086452d6497376313e56bd0c0b3e02a4a032b2e548ad831e03103b53becb"
+ },
+ {
+ "address": "fdac2b2c969f2f80d3dc205063f0660c2e299ce60841ea74e86f7237686d730a",
+ "content": "112726ba27f23a10564d1d06d032f9d96f03d3a01afa58ac44a201401dab"
+ },
+ {
+ "address": "fdc950e24a7f4301d4471ba2d22b569379e381584e35d5d827ea1b1c523961c9",
+ "content": "51629861dde4b6e6f85d817ddcce900a201800b1002fde6175dc3a16c37f"
+ },
+ {
+ "address": "fe1945ac4a3a0238e610b9bf6abd02d65bbf2e71f99c1a96c447ba3c5c612aed",
+ "content": "d65606042a8b1e4ddc0d0e6f918475bd25da6461a39c415f3f1be537834a"
+ },
+ {
+ "address": "fe78d104a593bc8305f231f88bb729b37cd69c34fc306ab6ef76b402ac5bb06c",
+ "content": "627bc4902f9065ff2990ef9d862aa24df3854e589d1b73e8dd7a8a21fe01"
+ },
+ {
+ "address": "fef0a3462942ad58b96828fba739f50fac55d18ada485efc9cc9df42940edb68",
+ "content": "e5df0345a2a0009fe56738a754772d01a180979d92532e5ae1d56563cc01"
+ },
+ {
+ "address": "ff1f7f14a33af77095e787226667dd2aae42fc302fcdb3590bc8aa74286a9ceb",
+ "content": "fde2dd3e31151cc8ceeffc136d6697e974be62a30282ee5e0a6ca1aa09b1"
+ },
+ {
+ "address": "ff20dc69d8f0b0e623d560861566c00b7f3c55af7aedf4fe460fb0ecee906fb1",
+ "content": "f75818138da91714e8e50589f16e7b4a78a8bc1380222e87f1020eb6688f"
+ },
+ {
+ "address": "ff306180e648f8293b41583606d837e93d338c5ca2e990bf5006aaaa9d765c57",
+ "content": "93ff31441f8b9ea667a998cce4cbafe428369a0b05a7fac387e9106f0d99"
+ },
+ {
+ "address": "ff5c3fcafc00d8e9308782e22531966dd253df38a3b9864043e123c40baa3aab",
+ "content": "52f7be291d5fab72c9120e7e656072e47f1eb982ee9a5e420e1fecd3a811"
+ },
+ {
+ "address": "ff84567982fbb5f104dff20967aae016ece5bd079cca9815a4ed1f166e79c4e0",
+ "content": "32862b8afdb4f945c92fd00d4edc15ba01bc0f7da936867a7bf54cce3956"
+ },
+ {
+ "address": "ffbd9447c4aa92dda582eb2473b609e8e0f1645b5baaa7010d0f28233179e017",
+ "content": "2691f343b853a9163c9f925a0375b348815bad9f640cbc6041ef258c6c9e"
+ }
+ ],
+ "size": 4303347835
+}
\ No newline at end of file
diff --git a/ant-core/wasm-tests/large-download.test.mjs b/ant-core/wasm-tests/large-download.test.mjs
new file mode 100644
index 00000000..05f502d9
--- /dev/null
+++ b/ant-core/wasm-tests/large-download.test.mjs
@@ -0,0 +1,353 @@
+import assert from "node:assert/strict";
+import test from "node:test";
+import { readFile, mkdtemp, rm } from "node:fs/promises";
+import { createWriteStream } from "node:fs";
+import { Writable } from "node:stream";
+import { tmpdir } from "node:os";
+import { join } from "node:path";
+import { BrowserNetworkClient } from "./client-fixture.mjs";
+import { encryptPublicFile } from "./pkg/ant_core.js";
+import { mockWebRtc } from "./mock-webrtc.mjs";
+
+const large = JSON.parse(await readFile(new URL("./fixtures/large-file.json", import.meta.url)));
+const records = large.records.map(record => ({
+ address: record.address, content: Uint8Array.from(Buffer.from(record.content, "hex")),
+}));
+const map = records.find(record => record.address === large.address);
+
+function fixture(source = records, node = {}) {
+ const rtc = mockWebRtc([node]);
+ for (const record of source) rtc.stores[0].set(record.address, record.content);
+ return { rtc, client: new BrowserNetworkClient(rtc.endpoints) };
+}
+
+const gets = rtc => rtc.requests.filter(r => r.method === "get_chunk").length;
+
+// Distinct, incompressible chunks, so every chunk is its own network GET.
+function randomBytes(length) {
+ const bytes = new Uint8Array(length);
+ let state = 0x9e3779b9;
+ for (let i = 0; i < length; i++) {
+ state ^= state << 13; state ^= state >>> 17; state ^= state << 5;
+ bytes[i] = state;
+ }
+ return bytes;
+}
+
+test("native files larger than 4 GiB support exact public and private seeks", async () => {
+ const { rtc, client } = fixture();
+ try {
+ for (const open of [() => client.openPublicFile(large.address),
+ () => client.openPrivateFile({ data_map: map.content })]) {
+ const reader = await open();
+ try {
+ assert.equal(reader.size, large.size);
+ assert(reader.size > 2 ** 32);
+ // Cross both the old 1 GB cap and the wasm32 position boundary.
+ for (const start of [1_000_000_000, 2 ** 32 - 8, 2 ** 32 + 17, large.size - 8]) {
+ const bytes = await reader.readRange(start, 32);
+ assert.deepEqual(bytes, new Uint8Array(Math.min(32, large.size - start)).fill(large.byte));
+ }
+ assert.equal((await reader.readRange(large.size, 1)).length, 0);
+ assert.equal((await reader.readRange(Number.MAX_SAFE_INTEGER, 1)).length, 0);
+ const before = gets(rtc);
+ for (const value of [-1, 0.5, NaN, Infinity, 2 ** 53]) {
+ await assert.rejects(reader.readRange(value, 1), /safe integer/);
+ await assert.rejects(reader.readRange(0, value), /safe integer/);
+ }
+ await assert.rejects(reader.readRange(0, 2 ** 32 + 1), /range reads are limited/);
+ assert.equal(gets(rtc), before);
+ } finally { reader.close(); }
+ }
+ } finally { client.close(); }
+});
+
+test("a complete native >4 GiB file streams with bounded writes and matching BLAKE3", { timeout: 180_000 }, async () => {
+ const { client } = fixture();
+ let reader;
+ let written = 0, largest = 0, closed = false;
+ try {
+ reader = await client.openPublicFile(large.address);
+ const sink = new WritableStream({
+ write(bytes) {
+ written += bytes.length;
+ largest = Math.max(largest, bytes.length);
+ assert.equal(bytes[0], large.byte);
+ assert.equal(bytes.at(-1), large.byte);
+ },
+ close() { closed = true; },
+ });
+ const result = await reader.pipeTo(sink);
+ assert.equal(written, large.size);
+ assert.equal(result.bytesWritten, large.size);
+ assert.equal(result.hash, large.hash);
+ assert(largest <= 4 * 1024 * 1024);
+ assert(closed);
+ assert.equal(sink.locked, false);
+ } finally { reader?.close(); client.close(); }
+});
+
+test("large-file memory budgets fail before content fetch, and allocation errors permit streaming", async () => {
+ // A budget rejection makes exactly the requests that resolving the file does.
+ const opened = fixture();
+ try { (await opened.client.openPublicFile(large.address)).close(); } finally { opened.client.close(); }
+ const maxMemoryBytes = 64 * 1024 * 1024;
+ for (const download of [
+ client => client.downloadPublicFile(large.address, undefined, undefined, { maxMemoryBytes }),
+ client => client.downloadPrivateFile({ data_map: map.content }, undefined, undefined, { maxMemoryBytes }),
+ ]) {
+ const { rtc, client } = fixture();
+ try {
+ await assert.rejects(download(client), /memory budget.*pipeTo/);
+ assert(gets(rtc) <= gets(opened.rtc), `${gets(rtc)} GETs for a budget rejection`);
+ } finally { client.close(); }
+ }
+
+ const { rtc, client } = fixture();
+ try {
+ for (const value of [-1, 1.5, Infinity, NaN, 2 ** 53]) {
+ await assert.rejects(client.downloadPublicFile(large.address, undefined, undefined, { maxMemoryBytes: value }), /safe integer/);
+ }
+ await assert.rejects(client.downloadPublicFile(large.address, 0), /positive integer/);
+ await assert.rejects(client.downloadPublicFile(large.address, undefined, undefined, { signal: {} }), /AbortSignal/);
+ assert.equal(gets(rtc), 0, "invalid arguments fail before any fetch");
+ } finally { client.close(); }
+});
+
+test("an AbortSignal cancels a complete download, including during retry waits", async () => {
+ const original = new TextEncoder().encode("Download cancellation.".repeat(300));
+ const encrypted = encryptPublicFile(original);
+ const missing = encrypted.records.find(record => record.address !== encrypted.address);
+ const { rtc, client } = fixture(encrypted.records.filter(record => record !== missing));
+ try {
+ const reason = new Error("stop downloading");
+ await assert.rejects(client.downloadPublicFile(encrypted.address, undefined, undefined, { signal: AbortSignal.abort(reason) }),
+ error => error === reason);
+ const controller = new AbortController();
+ const started = Date.now();
+ const pending = client.downloadPublicFile(encrypted.address, undefined, undefined, { signal: controller.signal });
+ setTimeout(() => controller.abort(reason), 100);
+ await assert.rejects(pending, error => error === reason);
+ assert(Date.now() - started < 5_000, `abort took ${Date.now() - started} ms`);
+ rtc.stores[0].set(missing.address, missing.content);
+ assert.deepEqual((await client.downloadPublicFile(encrypted.address)).content, original);
+ } finally { client.close(); }
+});
+
+test("pipeTo writes ranges beyond 4 GiB to disk", async () => {
+ const { client } = fixture();
+ const directory = await mkdtemp(join(tmpdir(), "ant-wasm-download-"));
+ let reader;
+ try {
+ reader = await client.openPublicFile(large.address);
+ const path = join(directory, "tail.bin");
+ const sink = Writable.toWeb(createWriteStream(path));
+ const start = 2 ** 32 - 8;
+ const result = await reader.pipeTo(sink, { start });
+ assert.equal(result.bytesWritten, large.size - start);
+ assert.deepEqual(await readFile(path), Buffer.alloc(large.size - start, large.byte));
+ assert.equal(sink.locked, false);
+ } finally { reader?.close(); client.close(); await rm(directory, { recursive: true, force: true }); }
+});
+
+test("pipeTo keeps fetching behind a blocked write only up to its 32 MiB buffer", async () => {
+ // Twelve distinct chunks: about 50 MB, more than one buffer.
+ const original = randomBytes(12 * 4_190_208);
+ const encrypted = encryptPublicFile(original);
+ // Slow GETs are still in flight when the first write blocks.
+ const { rtc, client } = fixture(encrypted.records, { delay: method => method === "get_chunk" ? 30 : 0 });
+ let reader;
+ try {
+ reader = await client.openPublicFile(encrypted.address);
+ let unblock, firstWrite;
+ const entered = new Promise(resolve => { firstWrite = resolve; });
+ const gate = new Promise(resolve => { unblock = resolve; });
+ const chunks = [];
+ let writes = 0;
+ const sink = new WritableStream({
+ async write(bytes) {
+ if (++writes === 1) { firstWrite(); await gate; }
+ chunks.push(bytes);
+ },
+ });
+ const before = gets(rtc);
+ const completion = reader.pipeTo(sink);
+ await Promise.race([entered, completion.then(() => assert.fail("pipeTo finished without writing"))]);
+ // Fetching continues behind the blocked write until the buffer is full,
+ // and stops there.
+ const bufferChunks = Math.floor(32 * 1024 * 1024 / 4_190_208);
+ const deadline = Date.now() + 10_000;
+ while (gets(rtc) - before < bufferChunks && Date.now() < deadline) {
+ await new Promise(resolve => setTimeout(resolve, 20));
+ }
+ assert.equal(gets(rtc) - before, bufferChunks, "chunks fetched behind one blocked write");
+ await new Promise(resolve => setTimeout(resolve, 200));
+ assert.equal(gets(rtc) - before, bufferChunks, "fetching stops at the buffer bound");
+ unblock();
+ const result = await completion;
+ assert.equal(result.bytesWritten, original.length);
+ assert.deepEqual(Buffer.concat(chunks), Buffer.from(original));
+ assert(chunks.every(chunk => chunk.length <= 4 * 1024 * 1024));
+ } finally { reader?.close(); client.close(); }
+});
+
+test("invalid pipeTo calls reject without touching the destination", async () => {
+ const { client } = fixture();
+ let reader;
+ try {
+ reader = await client.openPublicFile(large.address);
+ for (const [options, expected, close] of [
+ [{ end: large.size + 1 }, /outside the file/],
+ [{ start: 10, end: 5 }, /outside the file/],
+ [{ start: -1 }, /safe integer/],
+ [{ onProgress: "no" }, /onProgress must be a function/],
+ [{ signal: {} }, /AbortSignal/],
+ [{ signal: new EventTarget() }, /AbortSignal/],
+ [{}, /closed/, true],
+ ]) {
+ if (close) reader.close();
+ let aborted = false, closed = false;
+ const sink = new WritableStream({ write() { assert.fail("nothing is written"); }, close() { closed = true; }, abort() { aborted = true; } });
+ await assert.rejects(reader.pipeTo(sink, options), expected);
+ assert.equal(aborted, false);
+ assert.equal(closed, false);
+ assert.equal(sink.locked, false);
+ }
+ } finally { reader?.close(); client.close(); }
+});
+
+test("an AbortSignal cancels one pipeTo and leaves its reader open", async () => {
+ const { client } = fixture();
+ let reader;
+ try {
+ reader = await client.openPublicFile(large.address);
+ const controller = new AbortController();
+ const reason = new Error("user cancelled");
+ let writes = 0, aborted;
+ const sink = new WritableStream({
+ write() { writes++; controller.abort(reason); },
+ abort(error) { aborted = error; },
+ });
+ await assert.rejects(reader.pipeTo(sink, { start: 2 ** 32, signal: controller.signal }), error => error === reason);
+ assert.equal(writes, 1);
+ assert.equal(aborted, reason);
+ assert.equal(sink.locked, false);
+
+ const early = new WritableStream({ write() { assert.fail("an aborted signal writes nothing"); } });
+ await assert.rejects(reader.pipeTo(early, { signal: AbortSignal.abort(reason) }), error => error === reason);
+ assert.equal(early.locked, false);
+ assert.deepEqual(await reader.readRange(2 ** 32, 4), new Uint8Array(4).fill(large.byte));
+ } finally { reader?.close(); client.close(); }
+});
+
+test("an AbortSignal stops a pipeTo waiting to retry a missing record", async () => {
+ const original = new TextEncoder().encode("Retry cancellation.".repeat(300));
+ const encrypted = encryptPublicFile(original);
+ const missing = encrypted.records.find(record => record.address !== encrypted.address);
+ const { client } = fixture(encrypted.records.filter(record => record !== missing));
+ let reader;
+ try {
+ reader = await client.openPublicFile(encrypted.address);
+ const controller = new AbortController();
+ const started = Date.now();
+ const pending = reader.pipeTo(new WritableStream(), { signal: controller.signal });
+ setTimeout(() => controller.abort(new Error("stop")), 100);
+ await assert.rejects(pending, /stop/);
+ assert(Date.now() - started < 5_000, `abort took ${Date.now() - started} ms`);
+ } finally { reader?.close(); client.close(); }
+});
+
+test("an AbortSignal settles pipeTo even while a destination write is stalled", async () => {
+ const { client } = fixture();
+ let reader;
+ try {
+ reader = await client.openPublicFile(large.address);
+ const controller = new AbortController();
+ const reason = new Error("stalled destination");
+ let writing;
+ const stalled = new Promise(resolve => { writing = resolve; });
+ const sink = new WritableStream({ write() { writing(); return new Promise(() => {}); } });
+ const pending = reader.pipeTo(sink, { signal: controller.signal });
+ await stalled;
+ const started = Date.now();
+ controller.abort(reason);
+ await assert.rejects(pending, error => error === reason);
+ assert(Date.now() - started < 2_000, `abort took ${Date.now() - started} ms`);
+ } finally { reader?.close(); client.close(); }
+});
+
+test("an AbortSignal during the destination's close rejects pipeTo", async () => {
+ const original = new TextEncoder().encode("Abort while committing.".repeat(200));
+ const encrypted = encryptPublicFile(original);
+ const { client } = fixture(encrypted.records);
+ let reader;
+ try {
+ reader = await client.openPublicFile(encrypted.address);
+ const controller = new AbortController();
+ const reason = new Error("cancelled during commit");
+ let closing;
+ const committing = new Promise(resolve => { closing = resolve; });
+ const sink = new WritableStream({ close() { closing(); return new Promise(() => {}); } });
+ const pending = reader.pipeTo(sink, { signal: controller.signal });
+ await committing;
+ controller.abort(reason);
+ await assert.rejects(pending, error => error === reason);
+ } finally { reader?.close(); client.close(); }
+});
+
+test("a writer rejection stops a stream and releases its lock", async () => {
+ const { client } = fixture();
+ let reader;
+ try {
+ reader = await client.openPublicFile(large.address);
+ let writes = 0, closed = false;
+ const failure = new Error("disk full");
+ const sink = new WritableStream({ write() { writes++; throw failure; }, close() { closed = true; } });
+ await assert.rejects(reader.pipeTo(sink, { start: 2 ** 32 }), error => error === failure);
+ assert.equal(writes, 1);
+ assert.equal(closed, false);
+ assert.equal(sink.locked, false);
+ } finally { reader?.close(); client.close(); }
+});
+
+test("in-memory downloads use one JS output buffer and return recoverable allocation failures", async () => {
+ const original = new TextEncoder().encode("In-memory download round trip.".repeat(100));
+ const encrypted = encryptPublicFile(original);
+ const { client } = fixture(encrypted.records);
+ const NativeUint8Array = globalThis.Uint8Array;
+ let reader;
+ try {
+ const messages = [];
+ const result = await client.downloadPublicFile(encrypted.address, 2, message => messages.push(message),
+ { maxMemoryBytes: original.length });
+ assert.deepEqual(result.content, original);
+ assert.equal(result.file.chunks.length, 3);
+ // Probes time the first chunks by these messages.
+ const chunkProgress = messages.filter(message => message.startsWith("Downloaded chunk "));
+ assert.deepEqual(chunkProgress, ["Downloaded chunk 0/3", "Downloaded chunk 1/3", "Downloaded chunk 2/3", "Downloaded chunk 3/3"]);
+ const unset = await client.downloadPublicFile(encrypted.address, null, () => {});
+ assert.equal(unset.hash, result.hash);
+ globalThis.Uint8Array = class extends NativeUint8Array {
+ constructor(...args) {
+ if (args.length === 1 && args[0] === original.length) throw new RangeError("allocation refused");
+ super(...args);
+ }
+ };
+ await assert.rejects(client.downloadPublicFile(encrypted.address), /cannot allocate download buffer.*pipeTo/);
+ // An output failure is returned as the output's own error, not as bad data.
+ const refused = new RangeError("output refused");
+ globalThis.Uint8Array = class extends NativeUint8Array {
+ subarray(...args) {
+ if (this.length === original.length) throw refused;
+ return super.subarray(...args);
+ }
+ };
+ await assert.rejects(client.downloadPublicFile(encrypted.address), error => error === refused);
+ globalThis.Uint8Array = NativeUint8Array;
+ reader = await client.openPublicFile(encrypted.address);
+ const chunks = [];
+ const streamed = await reader.pipeTo(new WritableStream({ write(bytes) { chunks.push(bytes); } }));
+ assert.equal(streamed.hash, result.hash);
+ assert.deepEqual(Buffer.concat(chunks), Buffer.from(original));
+ } finally { globalThis.Uint8Array = NativeUint8Array; reader?.close(); client.close(); }
+});
diff --git a/ant-core/wasm-tests/mock-webrtc.mjs b/ant-core/wasm-tests/mock-webrtc.mjs
index b821d2d4..5338a32c 100644
--- a/ant-core/wasm-tests/mock-webrtc.mjs
+++ b/ant-core/wasm-tests/mock-webrtc.mjs
@@ -47,10 +47,12 @@ export function mockWebRtc(nodes = [{}], { gatheringMs = 0 } = {}) {
if (this.connection.connectionState === "failed") return;
// A real DataChannel copies the outgoing bytes. The mock re-enters WASM
// instead, where allocating the server argument can grow memory and
- // detach an outgoing view into that same memory. Copy before re-entry.
+ // detach an outgoing view into that same memory. Copy before re-entry,
+ // including loading the node's records below.
+ const outgoing = new Uint8Array(message);
// One node has one store, whichever of its channels wrote to it.
for (const [key, content] of stores[this.index]) this.server.set_record(key, content);
- let response = this.server.push(new Uint8Array(message));
+ let response = this.server.push(outgoing);
if (!response.length) return;
const method = this.server.last_method();
if (method === "put_chunk") {
diff --git a/docs/adr/ADR-0004-direct-browser-read-client.md b/docs/adr/ADR-0004-direct-browser-read-client.md
index ec38600c..e77e4628 100644
--- a/docs/adr/ADR-0004-direct-browser-read-client.md
+++ b/docs/adr/ADR-0004-direct-browser-read-client.md
@@ -2,7 +2,7 @@
- **Status:** Proposed
- **Date:** 2026-08-03
-- **Last amended:** 2026-09-25
+- **Last amended:** 2026-10-13
- **Decision owners:**
- **Reviewers:**
- **Supersedes:** none
@@ -655,3 +655,95 @@ in flight through the shared chunk cache. The bounded read-ahead described under
streaming reads keeps at most five, so repeat the playback comparison of six and
ten on it. The method, raw results and scripts are in
`docs/investigations/2026-09-29-browser-lookup-alpha`.
+
+## Large-file download destinations (2026-10-01)
+
+Related: [V2-1398](https://linear.app/autonominetwork/issue/V2-1398).
+
+The browser download limit is independent of upload limits. Root-map file sizes,
+seek-index offsets, and shared range arithmetic use `u64`; only chunk indices and
+individual buffer lengths use `usize`. The JavaScript facade accepts nonnegative
+safe-integer numbers, rejecting fractional, overflowing and imprecise positions.
+Manifest validation no longer rejects files over 1 GB; it caps a file's chunk
+list at 262,144 entries (about 1 TiB at the native chunk size) to bound the
+sorting and normalisation of an untrusted entry.
+
+A reader retains a `self_encryption::DataMapIndex` of the root map (added in
+self_encryption 0.36.2). It finds overlapping chunks with 64-bit positions and
+binary searches, and decrypts single chunks with their original indices and
+neighbouring source hashes, so self_encryption keeps sole ownership of its KDF,
+DataMap representation and stored ciphertext. Encrypted records are verified
+against their addresses, and each decrypted chunk against the size and source
+hash the map declares; decompression stops at the declared size. The same
+release moves the dependency's `DecryptionStream` range arithmetic onto the
+index, which removes its pointer-sized whole-file sums. The reader indexes the
+map when it opens, so a DataMap with non-contiguous indices fails to open rather
+than opening with read-ahead off as described under streaming reads. Read-ahead
+plans its windows over the same 64-bit index, so it follows reads past 4 GiB on
+wasm32.
+
+A complete download fetches chunks as the native one does: within the client's
+adaptive fetch cap and its `concurrency` argument, with missing records retried
+together in deferred rounds, so retry waits do not add up across records. Each
+chunk is decrypted as it arrives and copied straight into its place in one
+JavaScript `Uint8Array` allocated up front, so WASM memory holds only the records
+in flight, and `Downloaded chunk n/total` counts chunks as they land. The file is
+hashed afterwards, copied back in 4 MiB pieces. The optional `maxMemoryBytes`
+limits the allocation; allocation failure rejects before file-content transfer
+and directs the caller to streaming. Automatic free-memory detection and
+implicit disk spill are not portable browser capabilities; applications own the
+memory budget and the choice of a storage destination.
+
+`BrowserFileReader.pipeTo` must write in file order. It fetches chunks
+concurrently within the adaptive fetch cap, each retried on the deferred schedule
+on its own, and hands them on in file order. Fetching continues while the
+destination writes, holding at most 32 MiB of plaintext; a record waiting to
+retry keeps its place under the cap, so a missing record can hold a stream back
+for the 60 seconds of its retry schedule.
+
+`pipeTo(writable, { start?, end?, signal?, onProgress? })` writes the whole file
+or a half-open range to a caller-owned `WritableStream`, at most 4 MiB per write,
+awaiting each write. Like `ReadableStream.pipeTo`, it rejects invalid calls
+without touching the destination, closes the destination on success, aborts it
+on failure without waiting for a stalled write, and releases the writer lock.
+An abort while the destination is closing still rejects, but per the Streams
+specification the close completes, so the destination may already be committed.
+An `AbortSignal` cancels a `pipeTo` or a complete download, including resolution
+and retry waits. Closing a reader releases its read-ahead records and makes
+later calls fail; it no longer clears the client's shared, bounded chunk cache,
+which other readers may be using. The core does not open file pickers, own
+browser filesystem policy, or change the companion SDK.
+
+Removing only the 1 GB check was rejected because wasm32 offsets would still
+truncate around 4 GiB. Whole-file WASM buffering was rejected because it couples
+supported file size to linear-memory capacity. Disk-only output was rejected
+because small files and consumers needing bytes can use JavaScript memory.
+Routing complete downloads through the in-order stream was rejected: copying
+into a preallocated array needs no order, and the stream's 32 MiB bound and
+per-record retries would cap their concurrency and add up retry waits.
+Decompression of crafted records is bounded for browser reads by
+`DataMapIndex::decrypt_chunk`; native complete downloads still decrypt through
+`self_encryption::decrypt`, which does not bound it.
+
+This changes the public Rust browser descriptor's `size` from `usize` to `u64`
+and Rust signatures of affected WASM exports. `readRange` now rejects fractional,
+negative, missing and imprecise arguments that wasm-bindgen previously coerced.
+The download options object and `pipeTo` are additive. Native
+`data_download_range` keeps its signature. Wire, storage, payment and node
+behavior are unchanged. Upload size limits are unchanged.
+
+Content-buffer memory is bounded, but root-map/index memory still grows with the
+number of chunks. Streaming also depends on destination capacity; in-memory
+output depends on the engine's typed-array limits. The JavaScript facade supports
+positions through `Number.MAX_SAFE_INTEGER`, just under 8 PiB, rather than
+claiming literally unlimited file sizes.
+
+Validation includes a complete 4,303,347,835-byte native-encrypted fixture streamed
+through generated WASM with a matching BLAKE3; public/private seeks beyond 4 GiB;
+disk output; fetching bounded behind a blocked write; `AbortSignal` cancellation
+during retries, stalled writes and the destination's close; invalid calls that
+leave the destination untouched; writer, allocation and output errors; memory
+budgets; manifest validation; and native index, range and retry tests. The
+generated WASM tests use mocked WebRTC hosts with real Rust protocol and crypto
+processing. They do not establish real-browser or live-network compatibility by
+themselves.