From 667444cd0eb8917e2cf6e8f10773d46fb7f0f742 Mon Sep 17 00:00:00 2001 From: araspitzu Date: Tue, 2 Jul 2019 17:31:53 +0200 Subject: [PATCH 01/12] Check 'initialblockdownload' from bitcoind during startup (#1058) --- eclair-core/src/main/scala/fr/acinq/eclair/Setup.scala | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/Setup.scala b/eclair-core/src/main/scala/fr/acinq/eclair/Setup.scala index ef756db973..4a28c24770 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/Setup.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/Setup.scala @@ -124,6 +124,7 @@ class Setup(datadir: File, // Make sure wallet support is enabled in bitcoind. _ <- bitcoinClient.invoke("getbalance").recover { case _ => throw BitcoinWalletDisabledException } progress = (json \ "verificationprogress").extract[Double] + ibd = (json \ "initialblockdownload").extract[Boolean] blocks = (json \ "blocks").extract[Long] headers = (json \ "headers").extract[Long] chainHash <- bitcoinClient.invoke("getblockhash", 0).map(_.extract[String]).map(s => ByteVector32.fromValidHex(s)).map(_.reverse) @@ -133,16 +134,17 @@ class Setup(datadir: File, .filter(value => (value \ "spendable").extract[Boolean]) .map(value => (value \ "address").extract[String]) } - } yield (progress, chainHash, bitcoinVersion, unspentAddresses, blocks, headers) + } yield (progress, ibd, chainHash, bitcoinVersion, unspentAddresses, blocks, headers) // blocking sanity checks - val (progress, chainHash, bitcoinVersion, unspentAddresses, blocks, headers) = await(future, 30 seconds, "bicoind did not respond after 30 seconds") + val (progress, initialBlockDownload, chainHash, bitcoinVersion, unspentAddresses, blocks, headers) = await(future, 30 seconds, "bicoind did not respond after 30 seconds") assert(bitcoinVersion >= 170000, "Eclair requires Bitcoin Core 0.17.0 or higher") assert(chainHash == nodeParams.chainHash, s"chainHash mismatch (conf=${nodeParams.chainHash} != bitcoind=$chainHash)") if (chainHash != Block.RegtestGenesisBlock.hash) { assert(unspentAddresses.forall(address => !isPay2PubkeyHash(address)), "Make sure that all your UTXOS are segwit UTXOS and not p2pkh (check out our README for more details)") } - assert(progress > 0.999, s"bitcoind should be synchronized (progress=$progress") - assert(headers - blocks <= 1, s"bitcoind should be synchronized (headers=$headers blocks=$blocks") + assert(!initialBlockDownload, s"bitcoind should be synchronized (initialblockdownload=$initialBlockDownload)") + assert(progress > 0.999, s"bitcoind should be synchronized (progress=$progress)") + assert(headers - blocks <= 1, s"bitcoind should be synchronized (headers=$headers blocks=$blocks)") Bitcoind(bitcoinClient) case ELECTRUM => val addresses = config.hasPath("electrum") match { From f724efaa76b256048de18f706e9cb58ecbebd6aa Mon Sep 17 00:00:00 2001 From: Pierre-Marie Padiou Date: Wed, 3 Jul 2019 12:00:00 +0200 Subject: [PATCH 02/12] Close the channel if the funding tx never confirms (#1034) If we are fundee and after 5 days the funding isn't even in the mempool, then we give up waiting and consider the channel closed. Note that if the funding tx stays unconfirmed forever we won't give up waiting. If we are funder, we never give up until the funding tx is double spent, and we periodically republish it. This applies to states `WAIT_FOR_FUNDING_CONFIRMED` and `CLOSING` (and also `OFFLINE`/`SYNCING` when underlying state is `WAIT_FOR_FUNDING_CONFIRMED`). Also, added a generic way of passing context to `ElectrumClient` requests/responses. Fixes #1029. --- .../eclair/blockchain/WatcherTypes.scala | 5 +- .../bitcoind/BitcoinCoreWallet.scala | 26 +- .../blockchain/bitcoind/ZmqWatcher.scala | 16 +- .../bitcoind/rpc/ExtendedBitcoinClient.scala | 9 +- .../blockchain/electrum/ElectrumClient.scala | 28 +-- .../blockchain/electrum/ElectrumWallet.scala | 39 ++- .../blockchain/electrum/ElectrumWatcher.scala | 109 +++++---- .../electrum/db/sqlite/SqliteWalletDb.scala | 3 +- .../fr/acinq/eclair/channel/Channel.scala | 153 ++++++++---- .../acinq/eclair/channel/ChannelTypes.scala | 10 +- .../fr/acinq/eclair/channel/Helpers.scala | 17 -- .../fr/acinq/eclair/wire/ChannelCodecs.scala | 20 +- .../bitcoind/BitcoinCoreWalletSpec.scala | 6 + .../electrum/ElectrumClientPoolSpec.scala | 2 +- .../electrum/ElectrumClientSpec.scala | 2 +- .../ElectrumWalletSimulatedClientSpec.scala | 8 +- .../electrum/ElectrumWalletSpec.scala | 25 +- .../electrum/ElectrumWatcherSpec.scala | 34 ++- .../db/sqlite/SqliteWalletDbSpec.scala | 2 +- .../fr/acinq/eclair/channel/FuzzySpec.scala | 6 +- .../fr/acinq/eclair/channel/HelpersSpec.scala | 47 ++-- .../states/StateTestsHelperMethods.scala | 6 +- .../c/WaitForFundingConfirmedStateSpec.scala | 28 ++- .../c/WaitForFundingLockedStateSpec.scala | 6 +- .../channel/states/e/NormalStateSpec.scala | 36 +-- .../channel/states/h/ClosingStateSpec.scala | 227 +++++++++++++++--- .../interop/rustytests/RustyTestsSpec.scala | 6 +- 27 files changed, 599 insertions(+), 277 deletions(-) diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/WatcherTypes.scala b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/WatcherTypes.scala index fa9b82250e..4edc1d6496 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/WatcherTypes.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/WatcherTypes.scala @@ -68,7 +68,7 @@ final case class WatchLost(channel: ActorRef, txId: ByteVector32, minDepth: Long trait WatchEvent { def event: BitcoinEvent } -final case class WatchEventConfirmed(event: BitcoinEvent, blockHeight: Int, txIndex: Int) extends WatchEvent +final case class WatchEventConfirmed(event: BitcoinEvent, blockHeight: Int, txIndex: Int, tx: Transaction) extends WatchEvent final case class WatchEventSpent(event: BitcoinEvent, tx: Transaction) extends WatchEvent final case class WatchEventSpentBasic(event: BitcoinEvent) extends WatchEvent final case class WatchEventLost(event: BitcoinEvent) extends WatchEvent @@ -85,4 +85,7 @@ object UtxoStatus { } final case class ValidateResult(c: ChannelAnnouncement, fundingTx: Either[Throwable, (Transaction, UtxoStatus)]) +final case class GetTxWithMeta(txid: ByteVector32) +final case class GetTxWithMetaResponse(txid: ByteVector32, tx_opt: Option[Transaction], lastBlockTimestamp: Long) + // @formatter:on diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/BitcoinCoreWallet.scala b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/BitcoinCoreWallet.scala index a6a54f4982..f32856491e 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/BitcoinCoreWallet.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/BitcoinCoreWallet.scala @@ -27,6 +27,7 @@ import org.json4s.JsonAST._ import org.json4s.jackson.Serialization import scodec.bits.ByteVector +import scala.compat.Platform import scala.concurrent.{ExecutionContext, Future} /** @@ -54,7 +55,7 @@ class BitcoinCoreWallet(rpcClient: BitcoinJsonRPCClient)(implicit ec: ExecutionC val JBool(complete) = json \ "complete" if (!complete) { val message = (json \ "errors" \\ classOf[JString]).mkString(",") - throw new JsonRPCError(Error(-1, message)) + throw JsonRPCError(Error(-1, message)) } SignTransactionResponse(Transaction.read(hex), complete) }) @@ -69,8 +70,7 @@ class BitcoinCoreWallet(rpcClient: BitcoinJsonRPCClient)(implicit ec: ExecutionC def unlockOutpoints(outPoints: Seq[OutPoint])(implicit ec: ExecutionContext): Future[Boolean] = rpcClient.invoke("lockunspent", true, outPoints.toList.map(outPoint => Utxo(outPoint.txid.toString, outPoint.index))) collect { case JBool(result) => result } - def isTransactionOutputSpendable(txId: String, outputIndex: Int)(implicit ec: ExecutionContext): Future[Boolean] = rpcClient.invoke("gettxout", txId, outputIndex, true) collect { case j => j != JNull } - + def isTransactionOutputSpendable(txId: String, outputIndex: Int, includeMempool: Boolean)(implicit ec: ExecutionContext): Future[Boolean] = rpcClient.invoke("gettxout", txId, outputIndex, includeMempool) collect { case j => j != JNull } override def getBalance: Future[Satoshi] = rpcClient.invoke("getbalance") collect { case JDecimal(balance) => Satoshi(balance.bigDecimal.scaleByPowerOfTen(8).longValue()) } @@ -119,15 +119,25 @@ class BitcoinCoreWallet(rpcClient: BitcoinJsonRPCClient)(implicit ec: ExecutionC override def doubleSpent(tx: Transaction): Future[Boolean] = for { - exists <- getTransaction(tx.txid).map(_ => true).recover { case _ => false } + exists <- getTransaction(tx.txid) + .map(_ => true) // we have found the transaction + .recover { + case JsonRPCError(Error(_, message)) if message.contains("indexing") => + sys.error("Fatal error: bitcoind is indexing!!") + System.exit(1) // bitcoind is indexing, that's a fatal error!! + false // won't be reached + case _ => false + } doublespent <- if (exists) { - // if the tx is in the blockchain, it can't have been doublespent + // if the tx is in the blockchain, it can't have been double-spent Future.successful(false) } else { - // if the tx wasn't in the blockchain and one of it's input has been spent, it is doublespent - Future.sequence(tx.txIn.map(txIn => isTransactionOutputSpendable(txIn.outPoint.txid.toHex, txIn.outPoint.index.toInt))).map(_.exists(_ == false)) + // if the tx wasn't in the blockchain and one of it's input has been spent, it is double-spent + // NB: we don't look in the mempool, so it means that we will only consider that the tx has been double-spent if + // the overriding transaction has been confirmed at least once + Future.sequence(tx.txIn.map(txIn => isTransactionOutputSpendable(txIn.outPoint.txid.toHex, txIn.outPoint.index.toInt, includeMempool = false))).map(_.exists(_ == false)) } - } yield doublespent // TODO: should we check confirmations of the overriding tx? + } yield doublespent } diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/ZmqWatcher.scala b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/ZmqWatcher.scala index 845569a8d7..b6feb4afff 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/ZmqWatcher.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/ZmqWatcher.scala @@ -166,7 +166,7 @@ class ZmqWatcher(client: ExtendedBitcoinClient)(implicit ec: ExecutionContext = context become watching(watches, watchedUtxos, block2tx1, None) } else publish(tx) - case WatchEventConfirmed(BITCOIN_PARENT_TX_CONFIRMED(tx), blockHeight, _) => + case WatchEventConfirmed(BITCOIN_PARENT_TX_CONFIRMED(tx), blockHeight, _, _) => log.info(s"parent tx of txid=${tx.txid} has been confirmed") val blockCount = Globals.blockCount.get() val csvTimeout = Scripts.csvTimeout(tx) @@ -179,6 +179,8 @@ class ZmqWatcher(client: ExtendedBitcoinClient)(implicit ec: ExecutionContext = case ValidateRequest(ann) => client.validate(ann).pipeTo(sender) + case GetTxWithMeta(txid) => client.getTransactionMeta(txid.toString()).pipeTo(sender) + case Terminated(channel) => // we remove watches associated to dead actor val deprecatedWatches = watches.filter(_.channel == channel) @@ -207,10 +209,15 @@ class ZmqWatcher(client: ExtendedBitcoinClient)(implicit ec: ExecutionContext = def checkConfirmed(w: WatchConfirmed) = { log.debug(s"checking confirmations of txid=${w.txId}") + // NB: this is very inefficient since internally we call `getrawtransaction` three times, but it doesn't really + // matter because this only happens once, when the watched transaction has reached min_depth client.getTxConfirmations(w.txId.toString).map { case Some(confirmations) if confirmations >= w.minDepth => - client.getTransactionShortId(w.txId.toString).map { - case (height, index) => self ! TriggerEvent(w, WatchEventConfirmed(w.event, height, index)) + client.getTransaction(w.txId.toString).map { + case tx => + client.getTransactionShortId(w.txId.toString).map { + case (height, index) => self ! TriggerEvent(w, WatchEventConfirmed(w.event, height, index, tx)) + } } } } @@ -232,9 +239,6 @@ object ZmqWatcher { /** * The resulting map allows checking spent txes in constant time wrt number of watchers - * - * @param watches - * @return */ def addWatchedUtxos(m: Map[OutPoint, Set[Watch]], w: Watch): Map[OutPoint, Set[Watch]] = { utxo(w) match { diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/rpc/ExtendedBitcoinClient.scala b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/rpc/ExtendedBitcoinClient.scala index 4d798cae90..c7b7e492da 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/rpc/ExtendedBitcoinClient.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/bitcoind/rpc/ExtendedBitcoinClient.scala @@ -19,7 +19,7 @@ package fr.acinq.eclair.blockchain.bitcoind.rpc import fr.acinq.bitcoin._ import fr.acinq.eclair.ShortChannelId.coordinates import fr.acinq.eclair.TxCoordinates -import fr.acinq.eclair.blockchain.{UtxoStatus, ValidateResult} +import fr.acinq.eclair.blockchain.{GetTxWithMetaResponse, UtxoStatus, ValidateResult} import fr.acinq.eclair.wire.ChannelAnnouncement import org.json4s.JsonAST._ @@ -81,6 +81,13 @@ class ExtendedBitcoinClient(val rpcClient: BitcoinJsonRPCClient) { def getTransaction(txId: String)(implicit ec: ExecutionContext): Future[Transaction] = getRawTransaction(txId).map(raw => Transaction.read(raw)) + def getTransactionMeta(txId: String)(implicit ec: ExecutionContext): Future[GetTxWithMetaResponse] = + for { + tx_opt <- getTransaction(txId) map(Some(_)) recover { case _ => None } + blockchaininfo <- rpcClient.invoke("getblockchaininfo") + JInt(timestamp) = blockchaininfo \ "mediantime" + } yield GetTxWithMetaResponse(txid = ByteVector32.fromValidHex(txId), tx_opt, timestamp.toLong) + def isTransactionOutputSpendable(txId: String, outputIndex: Int, includeMempool: Boolean)(implicit ec: ExecutionContext): Future[Boolean] = for { json <- rpcClient.invoke("gettxout", txId, outputIndex, includeMempool) diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/electrum/ElectrumClient.scala b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/electrum/ElectrumClient.scala index 271d8039df..b60662583d 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/electrum/ElectrumClient.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/electrum/ElectrumClient.scala @@ -36,7 +36,7 @@ import io.netty.handler.ssl.util.InsecureTrustManagerFactory import io.netty.util.CharsetUtil import org.json4s.JsonAST._ import org.json4s.jackson.JsonMethods -import org.json4s.{DefaultFormats, JInt, JLong, JString} +import org.json4s.{DefaultFormats, Formats, JInt, JLong, JString} import scodec.bits.ByteVector import scala.annotation.tailrec @@ -352,8 +352,8 @@ object ElectrumClient { case class AddStatusListener(actor: ActorRef) case class RemoveStatusListener(actor: ActorRef) - sealed trait Request - sealed trait Response + sealed trait Request { def context_opt: Option[Any] = None } + sealed trait Response { def context_opt: Option[Any] = None } case class ServerVersion(clientName: String, protocolVersion: String) extends Request case class ServerVersionResponse(clientName: String, protocolVersion: String) extends Response @@ -383,8 +383,8 @@ object ElectrumClient { case class GetTransactionIdFromPosition(height: Int, tx_pos: Int, merkle: Boolean = false) extends Request case class GetTransactionIdFromPositionResponse(txid: ByteVector32, height: Int, tx_pos: Int, merkle: Seq[ByteVector32]) extends Response - case class GetTransaction(txid: ByteVector32) extends Request - case class GetTransactionResponse(tx: Transaction) extends Response + case class GetTransaction(txid: ByteVector32, override val context_opt: Option[Any] = None) extends Request + case class GetTransactionResponse(tx: Transaction, override val context_opt: Option[Any]) extends Response case class GetHeader(height: Int) extends Request case class GetHeaderResponse(height: Int, header: BlockHeader) extends Response @@ -397,8 +397,8 @@ object ElectrumClient { override def toString = s"GetHeadersResponse($start_height, ${headers.length}, ${headers.headOption}, ${headers.lastOption}, $max)" } - case class GetMerkle(txid: ByteVector32, height: Int) extends Request - case class GetMerkleResponse(txid: ByteVector32, merkle: List[ByteVector32], block_height: Int, pos: Int) extends Response { + case class GetMerkle(txid: ByteVector32, height: Int, override val context_opt: Option[Any] = None) extends Request + case class GetMerkleResponse(txid: ByteVector32, merkle: List[ByteVector32], block_height: Int, pos: Int, override val context_opt: Option[Any]) extends Response { lazy val root: ByteVector32 = { @tailrec def loop(pos: Int, hashes: Seq[ByteVector32]): ByteVector32 = { @@ -536,15 +536,15 @@ object ElectrumClient { case ScriptHashSubscription(scriptHash, _) => JsonRPCRequest(id = reqId, method = "blockchain.scripthash.subscribe", params = scriptHash.toString() :: Nil) case BroadcastTransaction(tx) => JsonRPCRequest(id = reqId, method = "blockchain.transaction.broadcast", params = Transaction.write(tx).toHex :: Nil) case GetTransactionIdFromPosition(height, tx_pos, merkle) => JsonRPCRequest(id = reqId, method = "blockchain.transaction.id_from_pos", params = height :: tx_pos :: merkle :: Nil) - case GetTransaction(txid) => JsonRPCRequest(id = reqId, method = "blockchain.transaction.get", params = txid :: Nil) + case GetTransaction(txid, _) => JsonRPCRequest(id = reqId, method = "blockchain.transaction.get", params = txid :: Nil) case HeaderSubscription(_) => JsonRPCRequest(id = reqId, method = "blockchain.headers.subscribe", params = Nil) case GetHeader(height) => JsonRPCRequest(id = reqId, method = "blockchain.block.header", params = height :: Nil) case GetHeaders(start_height, count, _) => JsonRPCRequest(id = reqId, method = "blockchain.block.headers", params = start_height :: count :: Nil) - case GetMerkle(txid, height) => JsonRPCRequest(id = reqId, method = "blockchain.transaction.get_merkle", params = txid :: height :: Nil) + case GetMerkle(txid, height, _) => JsonRPCRequest(id = reqId, method = "blockchain.transaction.get_merkle", params = txid :: height :: Nil) } def parseJsonResponse(request: Request, json: JsonRPCResponse): Response = { - implicit val formats = DefaultFormats + implicit val formats: Formats = DefaultFormats json.error match { case Some(error) => (request: @unchecked) match { case BroadcastTransaction(tx) => BroadcastTransactionResponse(tx, Some(error)) // for this request type, error are considered a "normal" response @@ -601,9 +601,9 @@ object ElectrumClient { val JArray(hashes) = json.result \ "merkle" val leaves = hashes collect { case JString(value) => ByteVector32.fromValidHex(value) } GetTransactionIdFromPositionResponse(ByteVector32.fromValidHex(tx_hash), height, tx_pos, leaves) - case GetTransaction(_) => + case GetTransaction(_, context_opt) => val JString(hex) = json.result - GetTransactionResponse(Transaction.read(hex)) + GetTransactionResponse(Transaction.read(hex), context_opt) case AddressSubscription(address, _) => json.result match { case JString(status) => AddressSubscriptionResponse(address, status) case _ => AddressSubscriptionResponse(address, "") @@ -631,12 +631,12 @@ object ElectrumClient { val bin = ByteVector.fromValidHex(hex).toArray val blockHeaders = bin.grouped(80).map(BlockHeader.read).toList GetHeadersResponse(start_height, blockHeaders, max) - case GetMerkle(txid, _) => + case GetMerkle(txid, _, context_opt) => val JArray(hashes) = json.result \ "merkle" val leaves = hashes collect { case JString(value) => ByteVector32.fromValidHex(value) } val blockHeight = intField(json.result, "block_height") val JInt(pos) = json.result \ "pos" - GetMerkleResponse(txid, leaves, blockHeight, pos.toInt) + GetMerkleResponse(txid, leaves, blockHeight, pos.toInt, context_opt) } } } diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/electrum/ElectrumWallet.scala b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/electrum/ElectrumWallet.scala index d9f3c1215b..428623f9e3 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/electrum/ElectrumWallet.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/electrum/ElectrumWallet.scala @@ -367,14 +367,14 @@ class ElectrumWallet(seed: ByteVector, client: ActorRef, params: ElectrumWallet. goto(DISCONNECTED) using data } - case Event(GetTransactionResponse(tx), data) => + case Event(GetTransactionResponse(tx, context_opt), data) => log.debug(s"received transaction ${tx.txid}") data.computeTransactionDelta(tx) match { case Some((received, sent, fee_opt)) => log.info(s"successfully connected txid=${tx.txid}") context.system.eventStream.publish(TransactionReceived(tx, data.computeTransactionDepth(tx.txid), received, sent, fee_opt, data.computeTimestamp(tx.txid, params.walletDb))) // when we have successfully processed a new tx, we retry all pending txes to see if they can be added now - data.pendingTransactions.foreach(self ! GetTransactionResponse(_)) + data.pendingTransactions.foreach(self ! GetTransactionResponse(_, context_opt)) val data1 = data.copy(transactions = data.transactions + (tx.txid -> tx), pendingTransactionRequests = data.pendingTransactionRequests - tx.txid, pendingTransactions = Nil) stay using persistAndNotify(data1) case None => @@ -384,14 +384,14 @@ class ElectrumWallet(seed: ByteVector, client: ActorRef, params: ElectrumWallet. stay using persistAndNotify(data1) } - case Event(ServerError(GetTransaction(txid), error), data) if data.pendingTransactionRequests.contains(txid) => + case Event(ServerError(GetTransaction(txid, _), error), data) if data.pendingTransactionRequests.contains(txid) => // server tells us that txid belongs to our wallet history, but cannot provide tx ? log.error(s"server cannot find history tx $txid: $error") sender ! PoisonPill goto(DISCONNECTED) using data - case Event(response@GetMerkleResponse(txid, _, height, _), data) => + case Event(response@GetMerkleResponse(txid, _, height, _, _), data) => data.blockchain.getHeader(height).orElse(params.walletDb.getHeader(height)) match { case Some(header) if header.hashMerkleRoot == response.root => log.info(s"transaction $txid has been verified") @@ -455,23 +455,10 @@ class ElectrumWallet(seed: ByteVector, client: ActorRef, params: ElectrumWallet. case Event(IsDoubleSpent(tx), data) => // detect if one of our transaction (i.e a transaction that spends from our wallet) has been double-spent - val isDoubleSpent = data.heights.get(tx.txid) match { - case Some(_) => - // this tx is either in the mempool or has been confirmed, which means that it hasn't been confirmed - false - case None => - // tx has not been published and is not in the mempool - - // list all our utxos that have been used - val ourSpentUtxos = data.transactions.values.flatMap(_.txIn).map(_.outPoint).toSet - - // list the tx utxos - val utxos = tx.txIn.map(_.outPoint).toSet - - // check if one of our transactions spends the same inputs as our tx, if this is the case, then the tx - // has been double spent - utxos.exists(utxo => ourSpentUtxos.contains(utxo)) - } + val isDoubleSpent = data.heights + .filter { case (_, height) => computeDepth(data.blockchain.height, height) >= 2 } // we only consider tx that have been confirmed + .flatMap { case (txid, _) => data.transactions.get(txid) } // we get the full tx + .exists(spendingTx => spendingTx.txIn.map(_.outPoint).toSet.intersect(tx.txIn.map(_.outPoint).toSet).nonEmpty && spendingTx.txid != tx.txid) // look for a tx that spend the same utxos and has a different txid stay() replying IsDoubleSpentResponse(tx, isDoubleSpent) case Event(ElectrumClient.ElectrumDisconnected, data) => @@ -672,7 +659,13 @@ object ElectrumWallet { } getOrElse None } - def computeDepth(currentHeight: Long, txHeight: Long): Long = currentHeight - txHeight + 1 + def computeDepth(currentHeight: Long, txHeight: Long): Long = + if (txHeight <= 0) { + // txHeight is 0 if tx in unconfirmed, and -1 if one of its inputs is unconfirmed + 0 + } else { + currentHeight - txHeight + 1 + } case class Utxo(key: ExtendedPrivateKey, item: ElectrumClient.UnspentItem) { def outPoint: OutPoint = item.outPoint @@ -739,7 +732,7 @@ object ElectrumWallet { } /** - * + * * @return the ids of transactions that belong to our wallet history for this script hash but that we don't have * and have no pending requests for. */ diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/electrum/ElectrumWatcher.scala b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/electrum/ElectrumWatcher.scala index f0195096f2..4f49a1f3cc 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/electrum/ElectrumWatcher.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/electrum/ElectrumWatcher.scala @@ -19,15 +19,15 @@ package fr.acinq.eclair.blockchain.electrum import java.net.InetSocketAddress import akka.actor.{Actor, ActorLogging, ActorRef, ActorSystem, Props, Stash, Terminated} -import fr.acinq.bitcoin.Crypto.PublicKey import fr.acinq.bitcoin.{BlockHeader, ByteVector32, Satoshi, Script, Transaction, TxIn, TxOut} import fr.acinq.eclair.blockchain._ -import fr.acinq.eclair.blockchain.electrum.ElectrumClient._ +import fr.acinq.eclair.blockchain.electrum.ElectrumClient.{SSL, computeScriptHash} import fr.acinq.eclair.channel.{BITCOIN_FUNDING_DEPTHOK, BITCOIN_FUNDING_SPENT, BITCOIN_PARENT_TX_CONFIRMED} import fr.acinq.eclair.transactions.Scripts import fr.acinq.eclair.{Globals, ShortChannelId, TxCoordinates} import scala.collection.SortedMap +import scala.collection.immutable.Queue class ElectrumWatcher(client: ActorRef) extends Actor with Stash with ActorLogging { @@ -36,33 +36,35 @@ class ElectrumWatcher(client: ActorRef) extends Actor with Stash with ActorLoggi override def unhandled(message: Any): Unit = message match { case ValidateRequest(c) => - log.info(s"blindly validating channel=$c") - val pubkeyScript = Script.write(Script.pay2wsh(Scripts.multiSig2of2(c.bitcoinKey1, c.bitcoinKey2))) - val TxCoordinates(_, _, outputIndex) = ShortChannelId.coordinates(c.shortChannelId) - val fakeFundingTx = Transaction( - version = 2, - txIn = Seq.empty[TxIn], - txOut = List.fill(outputIndex + 1)(TxOut(Satoshi(0), pubkeyScript)), // quick and dirty way to be sure that the outputIndex'th output is of the expected format - lockTime = 0) + log.info(s"blindly validating channel=$c") + val pubkeyScript = Script.write(Script.pay2wsh(Scripts.multiSig2of2(c.bitcoinKey1, c.bitcoinKey2))) + val TxCoordinates(_, _, outputIndex) = ShortChannelId.coordinates(c.shortChannelId) + val fakeFundingTx = Transaction( + version = 2, + txIn = Seq.empty[TxIn], + txOut = List.fill(outputIndex + 1)(TxOut(Satoshi(0), pubkeyScript)), // quick and dirty way to be sure that the outputIndex'th output is of the expected format + lockTime = 0) sender ! ValidateResult(c, Right((fakeFundingTx, UtxoStatus.Unspent))) case _ => log.warning(s"unhandled message $message") } - def receive = disconnected(Set.empty, Nil, SortedMap.empty) + def receive = disconnected(Set.empty, Queue.empty, SortedMap.empty, Queue.empty) - def disconnected(watches: Set[Watch], publishQueue: Seq[PublishAsap], block2tx: SortedMap[Long, Seq[Transaction]]): Receive = { + def disconnected(watches: Set[Watch], publishQueue: Queue[PublishAsap], block2tx: SortedMap[Long, Seq[Transaction]], getTxQueue: Queue[(GetTxWithMeta, ActorRef)]): Receive = { case ElectrumClient.ElectrumReady(_, _, _) => client ! ElectrumClient.HeaderSubscription(self) case ElectrumClient.HeaderSubscriptionResponse(height, header) => - watches.map(self ! _) - publishQueue.map(self ! _) - context become running(height, header, Set(), Map(), block2tx, Nil) - case watch: Watch => context become disconnected(watches + watch, publishQueue, block2tx) - case publish: PublishAsap => context become disconnected(watches, publishQueue :+ publish, block2tx) + watches.foreach(self ! _) + publishQueue.foreach(self ! _) + getTxQueue.foreach { case (msg, origin) => self.tell(msg, origin) } + context become running(height, header, Set(), Map(), block2tx, Queue.empty) + case watch: Watch => context become disconnected(watches + watch, publishQueue, block2tx, getTxQueue) + case publish: PublishAsap => context become disconnected(watches, publishQueue :+ publish, block2tx, getTxQueue) + case getTx: GetTxWithMeta => context become disconnected(watches, publishQueue, block2tx, getTxQueue :+ (getTx, sender)) } - def running(height: Int, tip: BlockHeader, watches: Set[Watch], scriptHashStatus: Map[ByteVector32, String], block2tx: SortedMap[Long, Seq[Transaction]], sent: Seq[Transaction]): Receive = { + def running(height: Int, tip: BlockHeader, watches: Set[Watch], scriptHashStatus: Map[ByteVector32, String], block2tx: SortedMap[Long, Seq[Transaction]], sent: Queue[Transaction]): Receive = { case ElectrumClient.HeaderSubscriptionResponse(newheight, newtip) if tip == newtip => () case ElectrumClient.HeaderSubscriptionResponse(newheight, newtip) => @@ -114,45 +116,51 @@ class ElectrumWatcher(client: ActorRef) extends Actor with Stash with ActorLoggi context become running(height, tip, watches, scriptHashStatus + (scriptHash -> status), block2tx, sent) case ElectrumClient.GetScriptHashHistoryResponse(_, history) => - // this is for WatchSpent/WatchSpentBasic - history.filter(_.height >= 0).map(item => client ! ElectrumClient.GetTransaction(item.tx_hash)) + // we retrieve the transaction before checking watches + history.filter(_.height >= 0).foreach { item => client ! ElectrumClient.GetTransaction(item.tx_hash, Some(item)) } + + case ElectrumClient.GetTransactionResponse(tx, Some(item: ElectrumClient.TransactionHistoryItem)) => + // this is for WatchSpent/WatchSpendBasic + val watchSpentTriggered = tx.txIn.map(_.outPoint).flatMap(outPoint => watches.collect { + case WatchSpent(channel, txid, pos, _, event) if txid == outPoint.txid && pos == outPoint.index.toInt => + log.info(s"output $txid:$pos spent by transaction ${tx.txid}") + channel ! WatchEventSpent(event, tx) + // NB: WatchSpent are permanent because we need to detect multiple spending of the funding tx + // They are never cleaned up but it is not a big deal for now (1 channel == 1 watch) + None + case w@WatchSpentBasic(channel, txid, pos, _, event) if txid == outPoint.txid && pos == outPoint.index.toInt => + log.info(s"output $txid:$pos spent by transaction ${tx.txid}") + channel ! WatchEventSpentBasic(event) + Some(w) + }).flatten // this is for WatchConfirmed - history.collect { - case ElectrumClient.TransactionHistoryItem(txheight, tx_hash) if txheight > 0 => watches.collect { - case WatchConfirmed(_, txid, _, minDepth, _) if txid == tx_hash => - val confirmations = height - txheight + 1 - log.info(s"txid=$txid was confirmed at height=$txheight and now has confirmations=$confirmations (currentHeight=${height})") - if (confirmations >= minDepth) { - // we need to get the tx position in the block - client ! GetMerkle(tx_hash, txheight) - } - } + watches.collect { + case WatchConfirmed(_, txid, _, minDepth, _) if txid == tx.txid => + val txheight = item.height + val confirmations = height - txheight + 1 + log.info(s"txid=$txid was confirmed at height=$txheight and now has confirmations=$confirmations (currentHeight=$height)") + if (confirmations >= minDepth) { + // we need to get the tx position in the block + client ! ElectrumClient.GetMerkle(txid, txheight, Some(tx)) + } } + context become running(height, tip, watches -- watchSpentTriggered, scriptHashStatus, block2tx, sent) - case ElectrumClient.GetMerkleResponse(tx_hash, _, txheight, pos) => + case ElectrumClient.GetMerkleResponse(tx_hash, _, txheight, pos, Some(tx: Transaction)) => val confirmations = height - txheight + 1 val triggered = watches.collect { case w@WatchConfirmed(channel, txid, _, minDepth, event) if txid == tx_hash && confirmations >= minDepth => log.info(s"txid=$txid had confirmations=$confirmations in block=$txheight pos=$pos") - channel ! WatchEventConfirmed(event, txheight.toInt, pos) + channel ! WatchEventConfirmed(event, txheight.toInt, pos, tx) w } context become running(height, tip, watches -- triggered, scriptHashStatus, block2tx, sent) - case ElectrumClient.GetTransactionResponse(spendingTx) => - val triggered = spendingTx.txIn.map(_.outPoint).flatMap(outPoint => watches.collect { - case WatchSpent(channel, txid, pos, _, event) if txid == outPoint.txid && pos == outPoint.index.toInt => - log.info(s"output $txid:$pos spent by transaction ${spendingTx.txid}") - channel ! WatchEventSpent(event, spendingTx) - // NB: WatchSpent are permanent because we need to detect multiple spending of the funding tx - // They are never cleaned up but it is not a big deal for now (1 channel == 1 watch) - None - case w@WatchSpentBasic(channel, txid, pos, _, event) if txid == outPoint.txid && pos == outPoint.index.toInt => - log.info(s"output $txid:$pos spent by transaction ${spendingTx.txid}") - channel ! WatchEventSpentBasic(event) - Some(w) - }).flatten - context become running(height, tip, watches -- triggered, scriptHashStatus, block2tx, sent) + case GetTxWithMeta(txid) => client ! ElectrumClient.GetTransaction(txid, Some(sender)) + + case ElectrumClient.GetTransactionResponse(tx, Some(origin: ActorRef)) => origin ! GetTxWithMetaResponse(tx.txid, Some(tx), tip.time) + + case ElectrumClient.ServerError(ElectrumClient.GetTransaction(txid, Some(origin: ActorRef)), _) => origin ! GetTxWithMetaResponse(txid, None, tip.time) case PublishAsap(tx) => val blockCount = Globals.blockCount.get() @@ -170,11 +178,11 @@ class ElectrumWatcher(client: ActorRef) extends Actor with Stash with ActorLoggi context become running(height, tip, watches, scriptHashStatus, block2tx1, sent) } else { log.info(s"publishing tx=$tx") - client ! BroadcastTransaction(tx) + client ! ElectrumClient.BroadcastTransaction(tx) context become running(height, tip, watches, scriptHashStatus, block2tx, sent :+ tx) } - case WatchEventConfirmed(BITCOIN_PARENT_TX_CONFIRMED(tx), blockHeight, _) => + case WatchEventConfirmed(BITCOIN_PARENT_TX_CONFIRMED(tx), blockHeight, _, _) => log.info(s"parent tx of txid=${tx.txid} has been confirmed") val blockCount = Globals.blockCount.get() val csvTimeout = Scripts.csvTimeout(tx) @@ -185,7 +193,7 @@ class ElectrumWatcher(client: ActorRef) extends Actor with Stash with ActorLoggi context become running(height, tip, watches, scriptHashStatus, block2tx1, sent) } else { log.info(s"publishing tx=$tx") - client ! BroadcastTransaction(tx) + client ! ElectrumClient.BroadcastTransaction(tx) context become running(height, tip, watches, scriptHashStatus, block2tx, sent :+ tx) } @@ -200,7 +208,7 @@ class ElectrumWatcher(client: ActorRef) extends Actor with Stash with ActorLoggi case ElectrumClient.ElectrumDisconnected => // we remember watches and keep track of tx that have not yet been published // we also re-send the txes that we previously sent but hadn't yet received the confirmation - context become disconnected(watches, sent.map(PublishAsap(_)), block2tx) + context become disconnected(watches, sent.map(PublishAsap), block2tx, Queue.empty) } } @@ -208,6 +216,7 @@ class ElectrumWatcher(client: ActorRef) extends Actor with Stash with ActorLoggi object ElectrumWatcher extends App { val system = ActorSystem() + import scala.concurrent.ExecutionContext.Implicits.global class Root extends Actor with ActorLogging { diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/electrum/db/sqlite/SqliteWalletDb.scala b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/electrum/db/sqlite/SqliteWalletDb.scala index 907cd45f7d..f817dc3e21 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/electrum/db/sqlite/SqliteWalletDb.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/blockchain/electrum/db/sqlite/SqliteWalletDb.scala @@ -145,7 +145,8 @@ object SqliteWalletDb { ("txid" | bytes32) :: ("merkle" | listOfN(uint16, bytes32)) :: ("block_height" | uint24) :: - ("pos" | uint24)).as[GetMerkleResponse] + ("pos" | uint24) :: + ("context_opt" | provide(Option.empty[Any]))).as[GetMerkleResponse] def serializeMerkleProof(proof: GetMerkleResponse): Array[Byte] = proofCodec.encode(proof).require.toByteArray diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/Channel.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/Channel.scala index 38a3609ba6..a4e4c9b0e9 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/Channel.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/Channel.scala @@ -210,6 +210,11 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId closing.nextRemoteCommitPublished.foreach(doPublish) closing.revokedCommitPublished.foreach(doPublish) closing.futureRemoteCommitPublished.foreach(doPublish) + + // if commitment number is zero, we also need to make sure that the funding tx has been published + if (closing.commitments.localCommit.index == 0 && closing.commitments.remoteCommit.index == 0) { + blockchain ! GetTxWithMeta(closing.commitments.commitInput.outPoint.txid) + } } // no need to go OFFLINE, we can directly switch to CLOSING goto(CLOSING) using closing @@ -241,26 +246,8 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId // TODO: should we wait for an acknowledgment from the watcher? blockchain ! WatchSpent(self, data.commitments.commitInput.outPoint.txid, data.commitments.commitInput.outPoint.index.toInt, data.commitments.commitInput.txOut.publicKeyScript, BITCOIN_FUNDING_SPENT) blockchain ! WatchLost(self, data.commitments.commitInput.outPoint.txid, nodeParams.minDepthBlocks, BITCOIN_FUNDING_LOST) - if (funding.commitments.localParams.isFunder) { // FUNDER - funding.fundingTx match { - case Some(fundingTx) => - log.debug(s"checking status of funding tx txid=${fundingTx.txid}") - wallet.doubleSpent(fundingTx).onComplete { - case Success(true) => - log.warning(s"funding tx has been double spent! cancelling channel fundingTxid=${fundingTx.txid} fundingTx=$fundingTx") - self ! BITCOIN_FUNDING_PUBLISH_FAILED - case Success(false) => () - case Failure(t) => log.error(t, s"error while testing status of funding tx fundingTxid=${fundingTx.txid}: ") - } - case _ => () - } - } else { // FUNDEE - // this is a bit tricky: let's say we shut down eclair right after someone opened a channel to us, and didn't start it up before a very long time - // we don't want the timeout to expire right away, because the watcher could be syncing or be busy, and may only notice the funding tx after some time - // so we always give us 10 minutes before doing anything - val delay = Funding.computeFundingTimeout(Platform.currentTime.milliseconds.toSeconds, funding.waitingSince, delay = FUNDING_TIMEOUT_FUNDEE, minDelay = 10 minutes) - context.system.scheduler.scheduleOnce(delay, self, BITCOIN_FUNDING_TIMEOUT) - } + // we make sure that the funding tx has been published + blockchain ! GetTxWithMeta(funding.commitments.commitInput.outPoint.txid) goto(OFFLINE) using data case _ => @@ -446,7 +433,6 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId log.info(s"waiting for them to publish the funding tx for channelId=$channelId fundingTxid=${commitInput.outPoint.txid}") blockchain ! WatchSpent(self, commitInput.outPoint.txid, commitInput.outPoint.index.toInt, commitments.commitInput.txOut.publicKeyScript, BITCOIN_FUNDING_SPENT) // TODO: should we wait for an acknowledgment from the watcher? blockchain ! WatchConfirmed(self, commitInput.outPoint.txid, commitments.commitInput.txOut.publicKeyScript, nodeParams.minDepthBlocks, BITCOIN_FUNDING_DEPTHOK) - val now = Platform.currentTime.milliseconds.toSeconds context.system.scheduler.scheduleOnce(FUNDING_TIMEOUT_FUNDEE, self, BITCOIN_FUNDING_TIMEOUT) goto(WAIT_FOR_FUNDING_CONFIRMED) using store(DATA_WAIT_FOR_FUNDING_CONFIRMED(commitments, None, now, None, Right(fundingSigned))) sending fundingSigned } @@ -531,17 +517,23 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId log.info(s"received their FundingLocked, deferring message") stay using d.copy(deferred = Some(msg)) // no need to store, they will re-send if we get disconnected - case Event(WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK, blockHeight, txIndex), DATA_WAIT_FOR_FUNDING_CONFIRMED(commitments, _, _, deferred, _)) => - log.info(s"channelId=${commitments.channelId} was confirmed at blockHeight=$blockHeight txIndex=$txIndex") - blockchain ! WatchLost(self, commitments.commitInput.outPoint.txid, nodeParams.minDepthBlocks, BITCOIN_FUNDING_LOST) - val nextPerCommitmentPoint = keyManager.commitmentPoint(commitments.localParams.channelKeyPath, 1) - val fundingLocked = FundingLocked(commitments.channelId, nextPerCommitmentPoint) - deferred.map(self ! _) - // this is the temporary channel id that we will use in our channel_update message, the goal is to be able to use our channel - // as soon as it reaches NORMAL state, and before it is announced on the network - // (this id might be updated when the funding tx gets deeply buried, if there was a reorg in the meantime) - val shortChannelId = ShortChannelId(blockHeight, txIndex, commitments.commitInput.outPoint.index.toInt) - goto(WAIT_FOR_FUNDING_LOCKED) using store(DATA_WAIT_FOR_FUNDING_LOCKED(commitments, shortChannelId, fundingLocked)) sending fundingLocked + case Event(WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK, blockHeight, txIndex, fundingTx), d@DATA_WAIT_FOR_FUNDING_CONFIRMED(commitments, _, _, deferred, _)) => + Try(Transaction.correctlySpends(commitments.localCommit.publishableTxs.commitTx.tx, Seq(fundingTx), ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS)) match { + case Success(_) => + log.info(s"channelId=${commitments.channelId} was confirmed at blockHeight=$blockHeight txIndex=$txIndex") + blockchain ! WatchLost(self, commitments.commitInput.outPoint.txid, nodeParams.minDepthBlocks, BITCOIN_FUNDING_LOST) + val nextPerCommitmentPoint = keyManager.commitmentPoint(commitments.localParams.channelKeyPath, 1) + val fundingLocked = FundingLocked(commitments.channelId, nextPerCommitmentPoint) + deferred.foreach(self ! _) + // this is the temporary channel id that we will use in our channel_update message, the goal is to be able to use our channel + // as soon as it reaches NORMAL state, and before it is announced on the network + // (this id might be updated when the funding tx gets deeply buried, if there was a reorg in the meantime) + val shortChannelId = ShortChannelId(blockHeight, txIndex, commitments.commitInput.outPoint.index.toInt) + goto(WAIT_FOR_FUNDING_LOCKED) using store(DATA_WAIT_FOR_FUNDING_LOCKED(commitments, shortChannelId, fundingLocked)) sending fundingLocked + case Failure(t) => + log.error(t, "") + goto(CLOSED) + } case Event(remoteAnnSigs: AnnouncementSignatures, d: DATA_WAIT_FOR_FUNDING_CONFIRMED) if d.commitments.announceChannel => log.debug(s"received remote announcement signatures, delaying") @@ -550,6 +542,8 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId context.system.scheduler.scheduleOnce(2 seconds, self, remoteAnnSigs) stay + case Event(getTxResponse: GetTxWithMetaResponse, d: DATA_WAIT_FOR_FUNDING_CONFIRMED) if getTxResponse.txid == d.commitments.commitInput.outPoint.txid => handleGetFundingTx(getTxResponse, d.waitingSince, d.fundingTx) + case Event(BITCOIN_FUNDING_PUBLISH_FAILED, d: DATA_WAIT_FOR_FUNDING_CONFIRMED) => handleFundingPublishFailed(d) case Event(BITCOIN_FUNDING_TIMEOUT, d: DATA_WAIT_FOR_FUNDING_CONFIRMED) => handleFundingTimeout(d) @@ -869,7 +863,7 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId case _ => stay } - case Event(WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, blockHeight, txIndex), d: DATA_NORMAL) if d.channelAnnouncement.isEmpty => + case Event(WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, blockHeight, txIndex, _), d: DATA_NORMAL) if d.channelAnnouncement.isEmpty => val shortChannelId = ShortChannelId(blockHeight, txIndex, d.commitments.commitInput.outPoint.index.toInt) log.info(s"funding tx is deeply buried at blockHeight=$blockHeight txIndex=$txIndex shortChannelId=$shortChannelId") // if final shortChannelId is different from the one we had before, we need to re-announce it @@ -1240,6 +1234,12 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId case Failure(cause) => handleCommandError(cause, c) } + case Event(getTxResponse: GetTxWithMetaResponse, d: DATA_CLOSING) if getTxResponse.txid == d.commitments.commitInput.outPoint.txid => handleGetFundingTx(getTxResponse, d.waitingSince, d.fundingTx) + + case Event(BITCOIN_FUNDING_PUBLISH_FAILED, d: DATA_CLOSING) => handleFundingPublishFailed(d) + + case Event(BITCOIN_FUNDING_TIMEOUT, d: DATA_CLOSING) => handleFundingTimeout(d) + case Event(WatchEventSpent(BITCOIN_FUNDING_SPENT, tx), d: DATA_CLOSING) => if (d.mutualClosePublished.map(_.txid).contains(tx.txid)) { // we already know about this tx, probably because we have published it ourselves after successful negotiation @@ -1279,7 +1279,7 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId // we can then use these preimages to fulfill origin htlcs log.info(s"processing BITCOIN_OUTPUT_SPENT with txid=${tx.txid} tx=$tx") val extracted = Closing.extractPreimages(d.commitments.localCommit, tx) - extracted map { case (htlc, fulfill) => + extracted foreach { case (htlc, fulfill) => d.commitments.originChannels.get(fulfill.id) match { case Some(origin) => log.info(s"fulfilling htlc #${fulfill.id} paymentHash=${sha256(fulfill.paymentPreimage)} origin=$origin") @@ -1298,7 +1298,7 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId } stay using store(d.copy(revokedCommitPublished = revokedCommitPublished1)) - case Event(WatchEventConfirmed(BITCOIN_TX_CONFIRMED(tx), blockHeight, _), d: DATA_CLOSING) => + case Event(WatchEventConfirmed(BITCOIN_TX_CONFIRMED(tx), blockHeight, _, _), d: DATA_CLOSING) => log.info(s"txid=${tx.txid} has reached mindepth, updating closing state") // first we check if this tx belongs to one of the current local/remote commits and update it val localCommitPublished1 = d.localCommitPublished.map(Closing.updateLocalCommitPublished(_, tx)) @@ -1436,12 +1436,14 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId // we're in OFFLINE state, we don't broadcast the new update right away, we will do that when next time we go to NORMAL state stay using store(d.copy(channelUpdate = channelUpdate)) replying "ok" + case Event(getTxResponse: GetTxWithMetaResponse, d: DATA_WAIT_FOR_FUNDING_CONFIRMED) if getTxResponse.txid == d.commitments.commitInput.outPoint.txid => handleGetFundingTx(getTxResponse, d.waitingSince, d.fundingTx) + case Event(BITCOIN_FUNDING_PUBLISH_FAILED, d: DATA_WAIT_FOR_FUNDING_CONFIRMED) => handleFundingPublishFailed(d) case Event(BITCOIN_FUNDING_TIMEOUT, d: DATA_WAIT_FOR_FUNDING_CONFIRMED) => handleFundingTimeout(d) // just ignore this, we will put a new watch when we reconnect, and we'll be notified again - case Event(WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK | BITCOIN_FUNDING_DEEPLYBURIED, _, _), _) => stay + case Event(WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK | BITCOIN_FUNDING_DEEPLYBURIED, _, _, _), _) => stay case Event(WatchEventSpent(BITCOIN_FUNDING_SPENT, tx), d: DATA_NEGOTIATING) if d.closingTxProposed.flatten.map(_.unsignedTx.txid).contains(tx.txid) => handleMutualClose(tx, Left(d)) @@ -1561,12 +1563,14 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId case Event(c@CurrentBlockCount(count), d: HasCommitments) if d.commitments.timedoutOutgoingHtlcs(count).nonEmpty => handleLocalError(HtlcTimedout(d.channelId, d.commitments.timedoutOutgoingHtlcs(count)), d, Some(c)) + case Event(getTxResponse: GetTxWithMetaResponse, d: DATA_WAIT_FOR_FUNDING_CONFIRMED) if getTxResponse.txid == d.commitments.commitInput.outPoint.txid => handleGetFundingTx(getTxResponse, d.waitingSince, d.fundingTx) + case Event(BITCOIN_FUNDING_PUBLISH_FAILED, d: DATA_WAIT_FOR_FUNDING_CONFIRMED) => handleFundingPublishFailed(d) case Event(BITCOIN_FUNDING_TIMEOUT, d: DATA_WAIT_FOR_FUNDING_CONFIRMED) => handleFundingTimeout(d) // just ignore this, we will put a new watch when we reconnect, and we'll be notified again - case Event(WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK | BITCOIN_FUNDING_DEEPLYBURIED, _, _), _) => stay + case Event(WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK | BITCOIN_FUNDING_DEEPLYBURIED, _, _, _), _) => stay case Event(WatchEventSpent(BITCOIN_FUNDING_SPENT, tx), d: DATA_NEGOTIATING) if d.closingTxProposed.flatten.map(_.unsignedTx.txid).contains(tx.txid) => handleMutualClose(tx, Left(d)) @@ -1742,7 +1746,52 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId stay replying Status.Failure(cause) } - def handleFundingPublishFailed(d: DATA_WAIT_FOR_FUNDING_CONFIRMED) = { + /** + * When we are funder, we use this function to detect when our funding tx has been double-spent (by another transaction + * that we made for some reason). If the funding tx has been double spent we can forget about the channel. + * + * @param fundingTx + */ + def checkDoubleSpent(fundingTx: Transaction) = { + log.debug(s"checking status of funding tx txid=${fundingTx.txid}") + wallet.doubleSpent(fundingTx).onComplete { + case Success(true) => + log.warning(s"funding tx has been double spent! fundingTxid=${fundingTx.txid} fundingTx=$fundingTx") + self ! BITCOIN_FUNDING_PUBLISH_FAILED + case Success(false) => () + case Failure(t) => log.error(t, s"error while testing status of funding tx fundingTxid=${fundingTx.txid}: ") + } + } + + def handleGetFundingTx(getTxResponse: GetTxWithMetaResponse, waitingSince: Long, fundingTx_opt: Option[Transaction]) = { + import getTxResponse._ + tx_opt match { + case Some(_) => () // the funding tx exists, nothing to do + case None => + fundingTx_opt match { + // ORDER MATTERS!! + case Some(fundingTx) => + // if we are funder, we never give up + log.info(s"republishing the funding tx...") + blockchain ! PublishAsap(fundingTx) + // we also check if the funding tx has been double-spent + checkDoubleSpent(fundingTx) + context.system.scheduler.scheduleOnce(1 day, blockchain, GetTxWithMeta(txid)) + case None if (now.seconds - waitingSince.seconds) > FUNDING_TIMEOUT_FUNDEE && (now.seconds - lastBlockTimestamp.seconds) < 1.hour => + // if we are fundee, we give up after some time + // NB: we want to be sure that the blockchain is in sync to prevent false negatives + log.warning(s"funding tx hasn't been published in ${(now.seconds - waitingSince.seconds).toDays} days and blockchain is fresh from ${(now.seconds - lastBlockTimestamp.seconds).toMinutes} minutes ago") + self ! BITCOIN_FUNDING_TIMEOUT + case None => + // let's wait a little longer + log.info(s"funding tx still hasn't been published in ${(now.seconds - waitingSince.seconds).toDays} days, will wait ${(FUNDING_TIMEOUT_FUNDEE - now.seconds + waitingSince.seconds).toDays} more days...") + context.system.scheduler.scheduleOnce(1 day, blockchain, GetTxWithMeta(txid)) + } + } + stay + } + + def handleFundingPublishFailed(d: HasCommitments) = { log.error(s"failed to publish funding tx") val exc = ChannelFundingError(d.channelId) val error = Error(d.channelId, exc.getMessage) @@ -1752,7 +1801,7 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId goto(CLOSED) sending error } - def handleFundingTimeout(d: DATA_WAIT_FOR_FUNDING_CONFIRMED) = { + def handleFundingTimeout(d: HasCommitments) = { log.warning(s"funding tx hasn't been confirmed in time, cancelling channel delay=$FUNDING_TIMEOUT_FUNDEE") val exc = FundingTxTimedout(d.channelId) val error = Error(d.channelId, exc.getMessage) @@ -1832,7 +1881,7 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId doPublish(closingTx) val nextData = d match { - case Left(negotiating) => DATA_CLOSING(negotiating.commitments, negotiating.closingTxProposed.flatten.map(_.unsignedTx), mutualClosePublished = closingTx :: Nil) + case Left(negotiating) => DATA_CLOSING(negotiating.commitments, fundingTx = None, waitingSince = now, negotiating.closingTxProposed.flatten.map(_.unsignedTx), mutualClosePublished = closingTx :: Nil) case Right(closing) => closing.copy(mutualClosePublished = closing.mutualClosePublished :+ closingTx) } goto(CLOSING) using store(nextData) @@ -1862,8 +1911,9 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId val nextData = d match { case closing: DATA_CLOSING => closing.copy(localCommitPublished = Some(localCommitPublished)) - case negotiating: DATA_NEGOTIATING => DATA_CLOSING(d.commitments, negotiating.closingTxProposed.flatten.map(_.unsignedTx), localCommitPublished = Some(localCommitPublished)) - case _ => DATA_CLOSING(d.commitments, mutualCloseProposed = Nil, localCommitPublished = Some(localCommitPublished)) + case negotiating: DATA_NEGOTIATING => DATA_CLOSING(d.commitments, fundingTx = None, waitingSince = now, negotiating.closingTxProposed.flatten.map(_.unsignedTx), localCommitPublished = Some(localCommitPublished)) + case waitForFundingConfirmed: DATA_WAIT_FOR_FUNDING_CONFIRMED => DATA_CLOSING(d.commitments, fundingTx = waitForFundingConfirmed.fundingTx, waitingSince = now, mutualCloseProposed = Nil, localCommitPublished = Some(localCommitPublished)) + case _ => DATA_CLOSING(d.commitments, fundingTx = None, waitingSince = now, mutualCloseProposed = Nil, localCommitPublished = Some(localCommitPublished)) } goto(CLOSING) using store(nextData) @@ -1936,8 +1986,9 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId val nextData = d match { case closing: DATA_CLOSING => closing.copy(remoteCommitPublished = Some(remoteCommitPublished)) - case negotiating: DATA_NEGOTIATING => DATA_CLOSING(d.commitments, negotiating.closingTxProposed.flatten.map(_.unsignedTx), remoteCommitPublished = Some(remoteCommitPublished)) - case _ => DATA_CLOSING(d.commitments, mutualCloseProposed = Nil, remoteCommitPublished = Some(remoteCommitPublished)) + case negotiating: DATA_NEGOTIATING => DATA_CLOSING(d.commitments, fundingTx = None, waitingSince = now, negotiating.closingTxProposed.flatten.map(_.unsignedTx), remoteCommitPublished = Some(remoteCommitPublished)) + case waitForFundingConfirmed: DATA_WAIT_FOR_FUNDING_CONFIRMED => DATA_CLOSING(d.commitments, fundingTx = waitForFundingConfirmed.fundingTx, waitingSince = now, mutualCloseProposed = Nil, remoteCommitPublished = Some(remoteCommitPublished)) + case _ => DATA_CLOSING(d.commitments, fundingTx = None, waitingSince = now, mutualCloseProposed = Nil, remoteCommitPublished = Some(remoteCommitPublished)) } goto(CLOSING) using store(nextData) @@ -1948,7 +1999,7 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId // if we are in this state, then this field is defined val remotePerCommitmentPoint = d.remoteChannelReestablish.myCurrentPerCommitmentPoint.get val remoteCommitPublished = Helpers.Closing.claimRemoteCommitMainOutput(keyManager, d.commitments, remotePerCommitmentPoint, commitTx) - val nextData = DATA_CLOSING(d.commitments, Nil, futureRemoteCommitPublished = Some(remoteCommitPublished)) + val nextData = DATA_CLOSING(d.commitments, fundingTx = None, waitingSince = now, Nil, futureRemoteCommitPublished = Some(remoteCommitPublished)) doPublish(remoteCommitPublished) goto(CLOSING) using store(nextData) @@ -1965,8 +2016,9 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId val nextData = d match { case closing: DATA_CLOSING => closing.copy(nextRemoteCommitPublished = Some(remoteCommitPublished)) - case negotiating: DATA_NEGOTIATING => DATA_CLOSING(d.commitments, negotiating.closingTxProposed.flatten.map(_.unsignedTx), nextRemoteCommitPublished = Some(remoteCommitPublished)) - case _ => DATA_CLOSING(d.commitments, mutualCloseProposed = Nil, nextRemoteCommitPublished = Some(remoteCommitPublished)) + case negotiating: DATA_NEGOTIATING => DATA_CLOSING(d.commitments, fundingTx = None, waitingSince = now, negotiating.closingTxProposed.flatten.map(_.unsignedTx), nextRemoteCommitPublished = Some(remoteCommitPublished)) + // NB: if there is a next commitment, we can't be in DATA_WAIT_FOR_FUNDING_CONFIRMED so we don't have the case where fundingTx is defined + case _ => DATA_CLOSING(d.commitments, fundingTx = None, waitingSince = now, mutualCloseProposed = Nil, nextRemoteCommitPublished = Some(remoteCommitPublished)) } goto(CLOSING) using store(nextData) @@ -2002,8 +2054,9 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId val nextData = d match { case closing: DATA_CLOSING => closing.copy(revokedCommitPublished = closing.revokedCommitPublished :+ revokedCommitPublished) - case negotiating: DATA_NEGOTIATING => DATA_CLOSING(d.commitments, negotiating.closingTxProposed.flatten.map(_.unsignedTx), revokedCommitPublished = revokedCommitPublished :: Nil) - case _ => DATA_CLOSING(d.commitments, mutualCloseProposed = Nil, revokedCommitPublished = revokedCommitPublished :: Nil) + case negotiating: DATA_NEGOTIATING => DATA_CLOSING(d.commitments, fundingTx = None, waitingSince = now, negotiating.closingTxProposed.flatten.map(_.unsignedTx), revokedCommitPublished = revokedCommitPublished :: Nil) + // NB: if there is a revoked commitment, we can't be in DATA_WAIT_FOR_FUNDING_CONFIRMED so we don't have the case where fundingTx is defined + case _ => DATA_CLOSING(d.commitments, fundingTx = None, waitingSince = now, mutualCloseProposed = Nil, revokedCommitPublished = revokedCommitPublished :: Nil) } goto(CLOSING) using store(nextData) sending error case None => @@ -2171,6 +2224,8 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId } + def now = Platform.currentTime.milliseconds.toSeconds + override def mdc(currentMessage: Any): MDC = { val id = currentMessage match { case INPUT_RESTORED(data) => data.channelId diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelTypes.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelTypes.scala index 1c65b9016d..d8413aa4e3 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelTypes.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelTypes.scala @@ -154,7 +154,7 @@ final case class DATA_WAIT_FOR_FUNDING_CREATED(temporaryChannelId: ByteVector32, final case class DATA_WAIT_FOR_FUNDING_SIGNED(channelId: ByteVector32, localParams: LocalParams, remoteParams: RemoteParams, fundingTx: Transaction, fundingTxFee: Satoshi, localSpec: CommitmentSpec, localCommitTx: CommitTx, remoteCommit: RemoteCommit, channelFlags: Byte, lastSent: FundingCreated) extends Data final case class DATA_WAIT_FOR_FUNDING_CONFIRMED(commitments: Commitments, fundingTx: Option[Transaction], - waitingSince: Long, + waitingSince: Long, // how long have we been waiting for the funding tx to confirm deferred: Option[FundingLocked], lastSent: Either[FundingCreated, FundingSigned]) extends Data with HasCommitments final case class DATA_WAIT_FOR_FUNDING_LOCKED(commitments: Commitments, shortChannelId: ShortChannelId, lastSent: FundingLocked) extends Data with HasCommitments @@ -171,10 +171,12 @@ final case class DATA_NEGOTIATING(commitments: Commitments, localShutdown: Shutdown, remoteShutdown: Shutdown, closingTxProposed: List[List[ClosingTxProposed]], // one list for every negotiation (there can be several in case of disconnection) bestUnpublishedClosingTx_opt: Option[Transaction]) extends Data with HasCommitments { - require(!closingTxProposed.isEmpty, "there must always be a list for the current negotiation") - require(!commitments.localParams.isFunder || closingTxProposed.forall(!_.isEmpty), "funder must have at least one closing signature for every negotation attempt because it initiates the closing") + require(closingTxProposed.nonEmpty, "there must always be a list for the current negotiation") + require(!commitments.localParams.isFunder || closingTxProposed.forall(_.nonEmpty), "funder must have at least one closing signature for every negotation attempt because it initiates the closing") } final case class DATA_CLOSING(commitments: Commitments, + fundingTx: Option[Transaction], // this will be non-empty if we are funder and we got in closing while waiting for our own tx to be published + waitingSince: Long, // how long since we initiated the closing mutualCloseProposed: List[Transaction], // all exchanged closing sigs are flattened, we use this only to keep track of what publishable tx they have mutualClosePublished: List[Transaction] = Nil, localCommitPublished: Option[LocalCommitPublished] = None, @@ -183,7 +185,7 @@ final case class DATA_CLOSING(commitments: Commitments, futureRemoteCommitPublished: Option[RemoteCommitPublished] = None, revokedCommitPublished: List[RevokedCommitPublished] = Nil) extends Data with HasCommitments { val spendingTxes = mutualClosePublished ::: localCommitPublished.map(_.commitTx).toList ::: remoteCommitPublished.map(_.commitTx).toList ::: nextRemoteCommitPublished.map(_.commitTx).toList ::: futureRemoteCommitPublished.map(_.commitTx).toList ::: revokedCommitPublished.map(_.commitTx) - require(spendingTxes.size > 0, "there must be at least one tx published in this state") + require(spendingTxes.nonEmpty, "there must be at least one tx published in this state") } final case class DATA_WAIT_FOR_REMOTE_PUBLISH_FUTURE_COMMITMENT(commitments: Commitments, remoteChannelReestablish: ChannelReestablish) extends Data with HasCommitments diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/Helpers.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/Helpers.scala index 8f88d7139a..f4609344f5 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/Helpers.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/Helpers.scala @@ -276,23 +276,6 @@ object Helpers { (localSpec, localCommitTx, remoteSpec, remoteCommitTx) } - /** - * This will return a delay, taking into account how much we already waited, and giving some slack - * - * @param now current timet - * @param waitingSince we have been waiting since that time - * @param delay the nominal delay that we were supposed to wait - * @param minDelay the minimum delay even if the nominal one has expired - * @return the delay we will actually wait - */ - def computeFundingTimeout(now: Long, waitingSince: Long, delay: FiniteDuration, minDelay: FiniteDuration): FiniteDuration = { - import scala.concurrent.duration._ - val a = waitingSince seconds - val b = now seconds - val d = delay - (b - a) - d.max(minDelay) - } - } /** diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/ChannelCodecs.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/ChannelCodecs.scala index b5164b485e..667b303b5a 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/ChannelCodecs.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/ChannelCodecs.scala @@ -287,8 +287,23 @@ object ChannelCodecs extends Logging { ("closingTxProposed" | listOfN(uint16, listOfN(uint16, closingTxProposedCodec))) :: ("bestUnpublishedClosingTx_opt" | optional(bool, txCodec))).as[DATA_NEGOTIATING] + // this is a decode-only codec compatible with versions 818199e and below, with placeholders for new fields + val DATA_CLOSING_COMPAT_06_Codec: Codec[DATA_CLOSING] = ( + ("commitments" | commitmentsCodec) :: + ("fundingTx" | provide[Option[Transaction]](None)) :: + ("waitingSince" | provide(Platform.currentTime.milliseconds.toSeconds)) :: + ("mutualCloseProposed" | listOfN(uint16, txCodec)) :: + ("mutualClosePublished" | listOfN(uint16, txCodec)) :: + ("localCommitPublished" | optional(bool, localCommitPublishedCodec)) :: + ("remoteCommitPublished" | optional(bool, remoteCommitPublishedCodec)) :: + ("nextRemoteCommitPublished" | optional(bool, remoteCommitPublishedCodec)) :: + ("futureRemoteCommitPublished" | optional(bool, remoteCommitPublishedCodec)) :: + ("revokedCommitPublished" | listOfN(uint16, revokedCommitPublishedCodec))).as[DATA_CLOSING].decodeOnly + val DATA_CLOSING_Codec: Codec[DATA_CLOSING] = ( - ("commitments" | commitmentsCodec) :: + ("commitments" | commitmentsCodec) :: + ("fundingTx" | optional(bool, txCodec)) :: + ("waitingSince" | int64) :: ("mutualCloseProposed" | listOfN(uint16, txCodec)) :: ("mutualClosePublished" | listOfN(uint16, txCodec)) :: ("localCommitPublished" | optional(bool, localCommitPublishedCodec)) :: @@ -314,13 +329,14 @@ object ChannelCodecs extends Logging { * More info here: https://github.com/scodec/scodec/issues/122 */ val stateDataCodec: Codec[HasCommitments] = ("version" | constant(0x00)) ~> discriminated[HasCommitments].by(uint16) + .typecase(0x09, DATA_CLOSING_Codec) .typecase(0x08, DATA_WAIT_FOR_FUNDING_CONFIRMED_Codec) .typecase(0x01, DATA_WAIT_FOR_FUNDING_CONFIRMED_COMPAT_01_Codec) .typecase(0x02, DATA_WAIT_FOR_FUNDING_LOCKED_Codec) .typecase(0x03, DATA_NORMAL_Codec) .typecase(0x04, DATA_SHUTDOWN_Codec) .typecase(0x05, DATA_NEGOTIATING_Codec) - .typecase(0x06, DATA_CLOSING_Codec) + .typecase(0x06, DATA_CLOSING_COMPAT_06_Codec) .typecase(0x07, DATA_WAIT_FOR_REMOTE_PUBLISH_FUTURE_COMMITMENT_Codec) } diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/bitcoind/BitcoinCoreWalletSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/bitcoind/BitcoinCoreWalletSpec.scala index 9403c05c8d..3af10b6426 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/bitcoind/BitcoinCoreWalletSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/bitcoind/BitcoinCoreWalletSpec.scala @@ -271,6 +271,12 @@ class BitcoinCoreWalletSpec extends TestKit(ActorSystem("test")) with BitcoindSe // let's publish tx2 bitcoinClient.invoke("sendrawtransaction", tx2.toString).pipeTo(sender.ref) val JString(_) = sender.expectMsgType[JValue] + // tx2 hasn't been confirmed so tx1 is still not considered double-spent + wallet.doubleSpent(tx1).pipeTo(sender.ref) + sender.expectMsg(false) + // let's confirm tx2 + sender.send(bitcoincli, BitcoinReq("generate", 1)) + sender.expectMsgType[JValue](10 seconds) // this time tx1 has been double spent wallet.doubleSpent(tx1).pipeTo(sender.ref) sender.expectMsg(true) diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/electrum/ElectrumClientPoolSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/electrum/ElectrumClientPoolSpec.scala index 99bf4fd8f2..7227c5f59d 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/electrum/ElectrumClientPoolSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/electrum/ElectrumClientPoolSpec.scala @@ -80,7 +80,7 @@ class ElectrumClientPoolSpec extends TestKit(ActorSystem("test")) with FunSuiteL test("get transaction") { probe.send(pool, GetTransaction(referenceTx.txid)) - val GetTransactionResponse(tx) = probe.expectMsgType[GetTransactionResponse](timeout) + val GetTransactionResponse(tx, _) = probe.expectMsgType[GetTransactionResponse](timeout) assert(tx == referenceTx) } diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/electrum/ElectrumClientSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/electrum/ElectrumClientSpec.scala index ebe8e90906..d69861caea 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/electrum/ElectrumClientSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/electrum/ElectrumClientSpec.scala @@ -79,7 +79,7 @@ class ElectrumClientSpec extends TestKit(ActorSystem("test")) with FunSuiteLike test("get transaction") { probe.send(client, GetTransaction(referenceTx.txid)) - val GetTransactionResponse(tx) = probe.expectMsgType[GetTransactionResponse] + val GetTransactionResponse(tx, _) = probe.expectMsgType[GetTransactionResponse] assert(tx == referenceTx) } diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/electrum/ElectrumWalletSimulatedClientSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/electrum/ElectrumWalletSimulatedClientSpec.scala index 32f40ec37a..99d5e9ba48 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/electrum/ElectrumWalletSimulatedClientSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/electrum/ElectrumWalletSimulatedClientSpec.scala @@ -187,7 +187,7 @@ class ElectrumWalletSimulatedClientSpec extends TestKit(ActorSystem("test")) wit } client.expectMsg(GetTransaction(tx.txid)) - wallet ! GetTransactionResponse(tx) + wallet ! GetTransactionResponse(tx, None) val TransactionReceived(_, _, Satoshi(100000), _, _, _) = listener.expectMsgType[TransactionReceived] // we think we have some unconfirmed funds val WalletReady(Satoshi(100000), _, _, _) = listener.expectMsgType[WalletReady] @@ -204,7 +204,7 @@ class ElectrumWalletSimulatedClientSpec extends TestKit(ActorSystem("test")) wit TestActor.KeepRunning } }) - probe.send(wallet, GetMerkleResponse(tx.txid, ByteVector32(ByteVector.fill(32)(1)) :: Nil, 2, 0)) + probe.send(wallet, GetMerkleResponse(tx.txid, ByteVector32(ByteVector.fill(32)(1)) :: Nil, 2, 0, None)) watcher.expectTerminated(probe.ref) awaitCond(wallet.stateName == ElectrumWallet.DISCONNECTED) @@ -319,9 +319,9 @@ class ElectrumWalletSimulatedClientSpec extends TestKit(ActorSystem("test")) wit sender ! ElectrumClient.ElectrumReady(headers.length, headers.last, InetSocketAddress.createUnresolved("0.0.0.0", 9735)) sender ! ElectrumClient.HeaderSubscriptionResponse(headers.length, headers.last) TestActor.KeepRunning - case request@GetTransaction(txid) => + case request@GetTransaction(txid, context_opt) => data.transactions.get(txid) match { - case Some(tx) => sender ! GetTransactionResponse(tx) + case Some(tx) => sender ! GetTransactionResponse(tx, context_opt) case None => sender ! ServerError(request, Error(0, s"unknwown tx $txid")) } diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/electrum/ElectrumWalletSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/electrum/ElectrumWalletSpec.scala index 3d53eb73e7..4771d98fe4 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/electrum/ElectrumWalletSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/electrum/ElectrumWalletSpec.scala @@ -310,19 +310,32 @@ class ElectrumWalletSpec extends TestKit(ActorSystem("test")) with FunSuiteLike probe.send(wallet, IsDoubleSpent(tx2)) probe.expectMsg(IsDoubleSpentResponse(tx2, false)) - // publish and confirm tx1 + // publish tx1 probe.send(wallet, BroadcastTransaction(tx1)) probe.expectMsg(BroadcastTransactionResponse(tx1, None)) - probe.send(bitcoincli, BitcoinReq("generate", 1)) + + awaitCond({ + probe.send(wallet, GetData) + val data = probe.expectMsgType[GetDataResponse].state + data.heights.contains(tx1.txid) && data.transactions.contains(tx1.txid) + }, max = 30 seconds, interval = 1 second) + + // as long as tx1 is unconfirmed tx2 won't be considered double-spent + probe.send(wallet, IsDoubleSpent(tx1)) + probe.expectMsg(IsDoubleSpentResponse(tx1, false)) + probe.send(wallet, IsDoubleSpent(tx2)) + probe.expectMsg(IsDoubleSpentResponse(tx2, false)) + + probe.send(bitcoincli, BitcoinReq("generate", 2)) probe.expectMsgType[JValue] awaitCond({ - val GetBalanceResponse(confirmed1, unconfirmed1) = getBalance(probe) - logger.info(s"current balance is $confirmed $unconfirmed") - confirmed1 < confirmed - Btc(1) + probe.send(wallet, GetData) + val data = probe.expectMsgType[GetDataResponse].state + data.heights.exists { case (txid, height) => txid == tx1.txid && data.transactions.contains(txid) && ElectrumWallet.computeDepth(data.blockchain.height, height) > 1 } }, max = 30 seconds, interval = 1 second) - // tx2 is double spent + // tx2 is double-spent probe.send(wallet, IsDoubleSpent(tx1)) probe.expectMsg(IsDoubleSpentResponse(tx1, false)) probe.send(wallet, IsDoubleSpent(tx2)) diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/electrum/ElectrumWatcherSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/electrum/ElectrumWatcherSpec.scala index 066c9fb61f..a5f963bd77 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/electrum/ElectrumWatcherSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/electrum/ElectrumWatcherSpec.scala @@ -21,15 +21,16 @@ import java.net.InetSocketAddress import akka.actor.{ActorSystem, Props} import akka.testkit.{TestKit, TestProbe} import fr.acinq.bitcoin.Crypto.PrivateKey -import fr.acinq.bitcoin.{Base58, OutPoint, SIGHASH_ALL, Satoshi, Script, ScriptFlags, ScriptWitness, SigVersion, Transaction, TxIn, TxOut} +import fr.acinq.bitcoin.{Base58, ByteVector32, OutPoint, SIGHASH_ALL, Satoshi, Script, ScriptFlags, ScriptWitness, SigVersion, Transaction, TxIn, TxOut} import fr.acinq.eclair.blockchain.bitcoind.BitcoindService import fr.acinq.eclair.blockchain.electrum.ElectrumClient.SSL import fr.acinq.eclair.blockchain.electrum.ElectrumClientPool.ElectrumServerAddress -import fr.acinq.eclair.blockchain.{WatchConfirmed, WatchEventConfirmed, WatchEventSpent, WatchSpent} +import fr.acinq.eclair.blockchain.{GetTxWithMetaResponse, GetTxWithMeta, WatchConfirmed, WatchEventConfirmed, WatchEventSpent, WatchSpent} import fr.acinq.eclair.channel.{BITCOIN_FUNDING_DEPTHOK, BITCOIN_FUNDING_SPENT} import grizzled.slf4j.Logging import org.json4s.JsonAST.{JArray, JString, JValue} import org.scalatest.{BeforeAndAfterAll, FunSuiteLike} +import scodec.bits._ import scala.concurrent.duration._ @@ -73,6 +74,7 @@ class ElectrumWatcherSpec extends TestKit(ActorSystem("test")) with FunSuiteLike listener.expectNoMsg(1 second) probe.send(bitcoincli, BitcoinReq("generate", 2)) val confirmed = listener.expectMsgType[WatchEventConfirmed](20 seconds) + assert(confirmed.tx.txid.toHex === txid) system.stop(watcher) } @@ -120,4 +122,32 @@ class ElectrumWatcherSpec extends TestKit(ActorSystem("test")) with FunSuiteLike val spent = listener.expectMsgType[WatchEventSpent](20 seconds) system.stop(watcher) } + + test("get transaction") { + val mainnetAddress = ElectrumServerAddress(new InetSocketAddress("electrum.acinq.co", 50002), SSL.STRICT) + val electrumClient = system.actorOf(Props(new ElectrumClientPool(Set(mainnetAddress)))) + val watcher = system.actorOf(Props(new ElectrumWatcher(electrumClient))) + //Thread.sleep(10000) + val probe = TestProbe() + + { + // tx is in the blockchain + val txid = ByteVector32(hex"c0b18008713360d7c30dae0940d88152a4bbb10faef5a69fefca5f7a7e1a06cc") + probe.send(watcher, GetTxWithMeta(txid)) + val res = probe.expectMsgType[GetTxWithMetaResponse] + assert(res.txid === txid) + assert(res.tx_opt === Some(Transaction.read("0100000001b5cbd7615a7494f60304695c180eb255113bd5effcf54aec6c7dfbca67f533a1010000006a473044022042115a5d1a489bbc9bd4348521b098025625c9b6c6474f84b96b11301da17a0602203ccb684b1d133ff87265a6017ef0fdd2d22dd6eef0725c57826f8aaadcc16d9d012103629aa3df53cad290078bbad26491f1e11f9c01697c65db0967561f6f142c993cffffffff02801015000000000017a914b8984d6344eed24689cdbc77adaf73c66c4fdd688734e9e818000000001976a91404607585722760691867b42d43701905736be47d88ac00000000"))) + assert(res.lastBlockTimestamp > System.currentTimeMillis().millis.toSeconds - 7200) // this server should be in sync + } + + { + // tx doesn't exist + val txid = ByteVector32(hex"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") + probe.send(watcher, GetTxWithMeta(txid)) + val res = probe.expectMsgType[GetTxWithMetaResponse] + assert(res.txid === txid) + assert(res.tx_opt === None) + assert(res.lastBlockTimestamp > System.currentTimeMillis().millis.toSeconds - 7200) // this server should be in sync + } + } } diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/electrum/db/sqlite/SqliteWalletDbSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/electrum/db/sqlite/SqliteWalletDbSpec.scala index 991efa4419..ae5937b31b 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/electrum/db/sqlite/SqliteWalletDbSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/blockchain/electrum/db/sqlite/SqliteWalletDbSpec.scala @@ -51,7 +51,7 @@ class SqliteWalletDbSpec extends FunSuite { def randomHistoryItems = (0 to random.nextInt(100)).map(_ => randomHistoryItem).toList - def randomProof = GetMerkleResponse(randomBytes32, ((0 until 10).map(_ => randomBytes32)).toList, random.nextInt(100000), 0) + def randomProof = GetMerkleResponse(randomBytes32, ((0 until 10).map(_ => randomBytes32)).toList, random.nextInt(100000), 0, None) def randomPersistentData = { val transactions = for (i <- 0 until random.nextInt(100)) yield randomTransaction diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/FuzzySpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/FuzzySpec.scala index 48a452e8ef..d44d98dc94 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/FuzzySpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/FuzzySpec.scala @@ -74,8 +74,10 @@ class FuzzySpec extends TestkitBaseClass with StateTestsHelperMethods with Loggi alice2blockchain.expectMsgType[WatchConfirmed] bob2blockchain.expectMsgType[WatchSpent] bob2blockchain.expectMsgType[WatchConfirmed] - alice ! WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK, 400000, 42) - bob ! WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK, 400000, 42) + awaitCond(alice.stateName == WAIT_FOR_FUNDING_CONFIRMED) + val fundingTx = alice.stateData.asInstanceOf[DATA_WAIT_FOR_FUNDING_CONFIRMED].fundingTx.get + alice ! WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK, 400000, 42, fundingTx) + bob ! WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK, 400000, 42, fundingTx) alice2blockchain.expectMsgType[WatchLost] bob2blockchain.expectMsgType[WatchLost] awaitCond(alice.stateName == NORMAL) diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/HelpersSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/HelpersSpec.scala index 37fd3ee662..0beca11ca5 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/HelpersSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/HelpersSpec.scala @@ -17,8 +17,8 @@ package fr.acinq.eclair.channel import fr.acinq.bitcoin.Transaction -import fr.acinq.eclair.channel.Helpers.Closing.{CurrentRemoteClose, LocalClose, MutualClose, NextRemoteClose, RecoveryClose, RevokedClose} -import fr.acinq.eclair.channel.Helpers.{Closing, Funding} +import fr.acinq.eclair.channel.Helpers.Closing +import fr.acinq.eclair.channel.Helpers.Closing._ import org.scalatest.FunSuite import scala.compat.Platform @@ -26,29 +26,6 @@ import scala.concurrent.duration._ class HelpersSpec extends FunSuite { - test("compute funding timeout") { - // we are supposed to wait 2 hours, and have already been waiting 1 hour, we have one more hour to wait - assert(Funding.computeFundingTimeout( - now = 7200, - waitingSince = 3600, - delay = 2 hours, - minDelay = 10 minutes) === (1 hour)) - - // we are supposed to wait 2 hours, and have already been waiting 9 hours, we'll wait the minimum of 10 minutes - assert(Funding.computeFundingTimeout( - now = 36000, - waitingSince = 3600, - delay = 2 hours, - minDelay = 10 minutes) === (10 minutes)) - - // we are supposed to wait 5 minutes, and have already been waiting 4 minutes, we'll wait the minimum of 10 minutes - assert(Funding.computeFundingTimeout( - now = 1240, - waitingSince = 1000, - delay = 5 minutes, - minDelay = 10 minutes) === (10 minutes)) - } - test("compute refresh delay") { import org.scalatest.Matchers._ implicit val log = akka.event.NoLogging @@ -70,6 +47,8 @@ class HelpersSpec extends FunSuite { assert(Closing.isClosingTypeAlreadyKnown( DATA_CLOSING( commitments = null, + fundingTx = None, + waitingSince = 0, mutualCloseProposed = tx1 :: tx2 :: tx3 :: Nil, mutualClosePublished = tx2 :: tx3 :: Nil, localCommitPublished = None, @@ -83,6 +62,8 @@ class HelpersSpec extends FunSuite { assert(Closing.isClosingTypeAlreadyKnown( DATA_CLOSING( commitments = null, + fundingTx = None, + waitingSince = 0, mutualCloseProposed = tx1 :: Nil, mutualClosePublished = tx1 :: Nil, localCommitPublished = Some(LocalCommitPublished( @@ -103,6 +84,8 @@ class HelpersSpec extends FunSuite { assert(Closing.isClosingTypeAlreadyKnown( DATA_CLOSING( commitments = null, + fundingTx = None, + waitingSince = 0, mutualCloseProposed = tx1 :: Nil, mutualClosePublished = tx1 :: Nil, localCommitPublished = Some(LocalCommitPublished( @@ -125,6 +108,8 @@ class HelpersSpec extends FunSuite { assert(Closing.isClosingTypeAlreadyKnown( DATA_CLOSING( commitments = null, + fundingTx = None, + waitingSince = 0, mutualCloseProposed = Nil, mutualClosePublished = Nil, localCommitPublished = Some(LocalCommitPublished( @@ -151,6 +136,8 @@ class HelpersSpec extends FunSuite { assert(Closing.isClosingTypeAlreadyKnown( DATA_CLOSING( commitments = null, + fundingTx = None, + waitingSince = 0, mutualCloseProposed = tx1 :: Nil, mutualClosePublished = tx1 :: Nil, localCommitPublished = Some(LocalCommitPublished( @@ -179,6 +166,8 @@ class HelpersSpec extends FunSuite { assert(Closing.isClosingTypeAlreadyKnown( DATA_CLOSING( commitments = null, + fundingTx = None, + waitingSince = 0, mutualCloseProposed = tx1 :: Nil, mutualClosePublished = tx1 :: Nil, localCommitPublished = Some(LocalCommitPublished( @@ -213,6 +202,8 @@ class HelpersSpec extends FunSuite { assert(Closing.isClosingTypeAlreadyKnown( DATA_CLOSING( commitments = null, + fundingTx = None, + waitingSince = 0, mutualCloseProposed = Nil, mutualClosePublished = Nil, localCommitPublished = None, @@ -232,6 +223,8 @@ class HelpersSpec extends FunSuite { assert(Closing.isClosingTypeAlreadyKnown( DATA_CLOSING( commitments = null, + fundingTx = None, + waitingSince = 0, mutualCloseProposed = Nil, mutualClosePublished = Nil, localCommitPublished = None, @@ -253,6 +246,8 @@ class HelpersSpec extends FunSuite { assert(Closing.isClosingTypeAlreadyKnown( DATA_CLOSING( commitments = null, + fundingTx = None, + waitingSince = 0, mutualCloseProposed = Nil, mutualClosePublished = Nil, localCommitPublished = Some(LocalCommitPublished( @@ -298,6 +293,8 @@ class HelpersSpec extends FunSuite { assert(Closing.isClosingTypeAlreadyKnown( DATA_CLOSING( commitments = null, + fundingTx = None, + waitingSince = 0, mutualCloseProposed = Nil, mutualClosePublished = Nil, localCommitPublished = Some(LocalCommitPublished( diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/StateTestsHelperMethods.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/StateTestsHelperMethods.scala index 28e5a39209..8ced14a635 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/StateTestsHelperMethods.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/StateTestsHelperMethods.scala @@ -91,8 +91,10 @@ trait StateTestsHelperMethods extends TestKitBase { alice2blockchain.expectMsgType[WatchConfirmed] bob2blockchain.expectMsgType[WatchSpent] bob2blockchain.expectMsgType[WatchConfirmed] - alice ! WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK, 400000, 42) - bob ! WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK, 400000, 42) + awaitCond(alice.stateName == WAIT_FOR_FUNDING_CONFIRMED) + val fundingTx = alice.stateData.asInstanceOf[DATA_WAIT_FOR_FUNDING_CONFIRMED].fundingTx.get + alice ! WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK, 400000, 42, fundingTx) + bob ! WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK, 400000, 42, fundingTx) alice2blockchain.expectMsgType[WatchLost] bob2blockchain.expectMsgType[WatchLost] alice2bob.expectMsgType[FundingLocked] diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/c/WaitForFundingConfirmedStateSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/c/WaitForFundingConfirmedStateSpec.scala index 48d3a4f24a..d3ef649aab 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/c/WaitForFundingConfirmedStateSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/c/WaitForFundingConfirmedStateSpec.scala @@ -18,11 +18,13 @@ package fr.acinq.eclair.channel.states.c import akka.actor.Status.Failure import akka.testkit.{TestFSMRef, TestProbe} -import fr.acinq.bitcoin.{ByteVector32, Transaction} +import fr.acinq.bitcoin.{ByteVector32, Satoshi, Script, Transaction} +import fr.acinq.eclair.randomKey import fr.acinq.eclair.TestConstants.{Alice, Bob} import fr.acinq.eclair.blockchain._ import fr.acinq.eclair.channel._ import fr.acinq.eclair.channel.states.StateTestsHelperMethods +import fr.acinq.eclair.transactions.Scripts.multiSig2of2 import fr.acinq.eclair.wire.{AcceptChannel, Error, FundingCreated, FundingLocked, FundingSigned, Init, OpenChannel} import fr.acinq.eclair.{TestConstants, TestkitBaseClass} import org.scalatest.Outcome @@ -63,7 +65,8 @@ class WaitForFundingConfirmedStateSpec extends TestkitBaseClass with StateTestsH test("recv FundingLocked") { f => import f._ // make bob send a FundingLocked msg - bob ! WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK, 42000, 42) + val fundingTx = alice.stateData.asInstanceOf[DATA_WAIT_FOR_FUNDING_CONFIRMED].fundingTx.get + bob ! WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK, 42000, 42, fundingTx) val msg = bob2alice.expectMsgType[FundingLocked] bob2alice.forward(alice) awaitCond(alice.stateData.asInstanceOf[DATA_WAIT_FOR_FUNDING_CONFIRMED].deferred.contains(msg)) @@ -72,12 +75,31 @@ class WaitForFundingConfirmedStateSpec extends TestkitBaseClass with StateTestsH test("recv BITCOIN_FUNDING_DEPTHOK") { f => import f._ - alice ! WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK, 42000, 42) + val fundingTx = alice.stateData.asInstanceOf[DATA_WAIT_FOR_FUNDING_CONFIRMED].fundingTx.get + alice ! WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK, 42000, 42, fundingTx) awaitCond(alice.stateName == WAIT_FOR_FUNDING_LOCKED) alice2blockchain.expectMsgType[WatchLost] alice2bob.expectMsgType[FundingLocked] } + test("recv BITCOIN_FUNDING_DEPTHOK (bad funding pubkey script)") { f => + import f._ + val fundingTx = alice.stateData.asInstanceOf[DATA_WAIT_FOR_FUNDING_CONFIRMED].fundingTx.get + val badOutputScript = fundingTx.txOut(0).copy(publicKeyScript = Script.write(multiSig2of2(randomKey.publicKey, randomKey.publicKey))) + val badFundingTx = fundingTx.copy(txOut = Seq(badOutputScript)) + alice ! WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK, 42000, 42, badFundingTx) + awaitCond(alice.stateName == CLOSED) + } + + test("recv BITCOIN_FUNDING_DEPTHOK (bad funding amount)") { f => + import f._ + val fundingTx = alice.stateData.asInstanceOf[DATA_WAIT_FOR_FUNDING_CONFIRMED].fundingTx.get + val badOutputAmount = fundingTx.txOut(0).copy(amount = Satoshi(1234567)) + val badFundingTx = fundingTx.copy(txOut = Seq(badOutputAmount)) + alice ! WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK, 42000, 42, badFundingTx) + awaitCond(alice.stateName == CLOSED) + } + test("recv BITCOIN_FUNDING_PUBLISH_FAILED") { f => import f._ alice ! BITCOIN_FUNDING_PUBLISH_FAILED diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/c/WaitForFundingLockedStateSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/c/WaitForFundingLockedStateSpec.scala index e8f71ae678..de4fa0ea27 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/c/WaitForFundingLockedStateSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/c/WaitForFundingLockedStateSpec.scala @@ -57,8 +57,10 @@ class WaitForFundingLockedStateSpec extends TestkitBaseClass with StateTestsHelp alice2blockchain.expectMsgType[WatchConfirmed] bob2blockchain.expectMsgType[WatchSpent] bob2blockchain.expectMsgType[WatchConfirmed] - alice ! WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK, 400000, 42) - bob ! WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK, 400000, 42) + awaitCond(alice.stateName == WAIT_FOR_FUNDING_CONFIRMED) + val fundingTx = alice.stateData.asInstanceOf[DATA_WAIT_FOR_FUNDING_CONFIRMED].fundingTx.get + alice ! WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK, 400000, 42, fundingTx) + bob ! WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK, 400000, 42, fundingTx) alice2blockchain.expectMsgType[WatchLost] bob2blockchain.expectMsgType[WatchLost] alice2bob.expectMsgType[FundingLocked] diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/e/NormalStateSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/e/NormalStateSpec.scala index 5e9f0696f1..768583a3d4 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/e/NormalStateSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/e/NormalStateSpec.scala @@ -2036,7 +2036,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods { test("recv BITCOIN_FUNDING_DEEPLYBURIED", Tag("channels_public")) { f => import f._ val sender = TestProbe() - sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42)) + sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42, null)) val annSigs = alice2bob.expectMsgType[AnnouncementSignatures] // public channel: we don't send the channel_update directly to the peer alice2bob.expectNoMsg(1 second) @@ -2048,7 +2048,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods { test("recv BITCOIN_FUNDING_DEEPLYBURIED (short channel id changed)", Tag("channels_public")) { f => import f._ val sender = TestProbe() - sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400001, 22)) + sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400001, 22, null)) val annSigs = alice2bob.expectMsgType[AnnouncementSignatures] // public channel: we don't send the channel_update directly to the peer alice2bob.expectNoMsg(1 second) @@ -2060,7 +2060,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods { test("recv BITCOIN_FUNDING_DEEPLYBURIED (private channel)") { f => import f._ val sender = TestProbe() - sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42)) + sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42, null)) // private channel: we send the channel_update directly to the peer val channelUpdate = alice2bob.expectMsgType[ChannelUpdate] awaitCond(alice.stateData.asInstanceOf[DATA_NORMAL].shortChannelId == channelUpdate.shortChannelId && alice.stateData.asInstanceOf[DATA_NORMAL].buried == true) @@ -2071,7 +2071,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods { test("recv BITCOIN_FUNDING_DEEPLYBURIED (private channel, short channel id changed)") { f => import f._ val sender = TestProbe() - sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400001, 22)) + sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400001, 22, null)) // private channel: we send the channel_update directly to the peer val channelUpdate = alice2bob.expectMsgType[ChannelUpdate] awaitCond(alice.stateData.asInstanceOf[DATA_NORMAL].shortChannelId == channelUpdate.shortChannelId && alice.stateData.asInstanceOf[DATA_NORMAL].buried == true) @@ -2084,9 +2084,9 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods { import f._ val initialState = alice.stateData.asInstanceOf[DATA_NORMAL] val sender = TestProbe() - sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42)) + sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42, null)) val annSigsA = alice2bob.expectMsgType[AnnouncementSignatures] - sender.send(bob, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42)) + sender.send(bob, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42, null)) val annSigsB = bob2alice.expectMsgType[AnnouncementSignatures] import initialState.commitments.{localParams, remoteParams} val channelAnn = Announcements.makeChannelAnnouncement(Alice.nodeParams.chainHash, annSigsA.shortChannelId, Alice.nodeParams.nodeId, remoteParams.nodeId, Alice.keyManager.fundingPublicKey(localParams.channelKeyPath).publicKey, remoteParams.fundingPubKey, annSigsA.nodeSignature, annSigsB.nodeSignature, annSigsA.bitcoinSignature, annSigsB.bitcoinSignature) @@ -2103,9 +2103,9 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods { import f._ val initialState = alice.stateData.asInstanceOf[DATA_NORMAL] val sender = TestProbe() - sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 42, 10)) + sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 42, 10, null)) val annSigsA = alice2bob.expectMsgType[AnnouncementSignatures] - sender.send(bob, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 42, 10)) + sender.send(bob, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 42, 10, null)) val annSigsB = bob2alice.expectMsgType[AnnouncementSignatures] import initialState.commitments.{localParams, remoteParams} val channelAnn = Announcements.makeChannelAnnouncement(Alice.nodeParams.chainHash, annSigsA.shortChannelId, Alice.nodeParams.nodeId, remoteParams.nodeId, Alice.keyManager.fundingPublicKey(localParams.channelKeyPath).publicKey, remoteParams.fundingPubKey, annSigsA.nodeSignature, annSigsB.nodeSignature, annSigsA.bitcoinSignature, annSigsB.bitcoinSignature) @@ -2122,8 +2122,8 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods { test("recv BroadcastChannelUpdate", Tag("channels_public")) { f => import f._ val sender = TestProbe() - sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42)) - sender.send(bob, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42)) + sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42, null)) + sender.send(bob, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42, null)) bob2alice.expectMsgType[AnnouncementSignatures] bob2alice.forward(alice) val update1 = channelUpdateListener.expectMsgType[LocalChannelUpdate] @@ -2138,8 +2138,8 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods { test("recv BroadcastChannelUpdate (no changes)", Tag("channels_public")) { f => import f._ val sender = TestProbe() - sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42)) - sender.send(bob, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42)) + sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42, null)) + sender.send(bob, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42, null)) bob2alice.expectMsgType[AnnouncementSignatures] bob2alice.forward(alice) channelUpdateListener.expectMsgType[LocalChannelUpdate] @@ -2153,7 +2153,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods { test("recv INPUT_DISCONNECTED") { f => import f._ val sender = TestProbe() - sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42)) + sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42, null)) val update1a = alice2bob.expectMsgType[ChannelUpdate] assert(Announcements.isEnabled(update1a.channelFlags) == true) @@ -2167,7 +2167,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods { test("recv INPUT_DISCONNECTED (with pending unsigned htlcs)") { f => import f._ val sender = TestProbe() - sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42)) + sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42, null)) val update1a = alice2bob.expectMsgType[ChannelUpdate] assert(Announcements.isEnabled(update1a.channelFlags) == true) val (_, htlc1) = addHtlc(10000, alice, bob, alice2bob, bob2alice) @@ -2189,8 +2189,8 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods { test("recv INPUT_DISCONNECTED (public channel)", Tag("channels_public")) { f => import f._ val sender = TestProbe() - sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42)) - sender.send(bob, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42)) + sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42, null)) + sender.send(bob, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42, null)) bob2alice.expectMsgType[AnnouncementSignatures] bob2alice.forward(alice) val update1 = channelUpdateListener.expectMsgType[LocalChannelUpdate] @@ -2205,8 +2205,8 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods { test("recv INPUT_DISCONNECTED (public channel, with pending unsigned htlcs)", Tag("channels_public")) { f => import f._ val sender = TestProbe() - sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42)) - sender.send(bob, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42)) + sender.send(alice, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42, null)) + sender.send(bob, WatchEventConfirmed(BITCOIN_FUNDING_DEEPLYBURIED, 400000, 42, null)) bob2alice.expectMsgType[AnnouncementSignatures] bob2alice.forward(alice) alice2bob.expectMsgType[AnnouncementSignatures] diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/h/ClosingStateSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/h/ClosingStateSpec.scala index c2a53b9b62..ec19d818e7 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/h/ClosingStateSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/h/ClosingStateSpec.scala @@ -21,7 +21,8 @@ import java.util.UUID import akka.actor.Status import akka.actor.Status.Failure import akka.testkit.{TestFSMRef, TestProbe} -import fr.acinq.bitcoin.{ByteVector32, ByteVector64, OutPoint, ScriptFlags, Transaction, TxIn} +import fr.acinq.bitcoin.{ByteVector32, OutPoint, ScriptFlags, Transaction, TxIn} +import fr.acinq.eclair.TestConstants.{Alice, Bob} import fr.acinq.eclair.blockchain._ import fr.acinq.eclair.blockchain.fee.FeeratesPerKw import fr.acinq.eclair.channel.states.StateTestsHelperMethods @@ -30,9 +31,10 @@ import fr.acinq.eclair.payment._ import fr.acinq.eclair.transactions.{Scripts, Transactions} import fr.acinq.eclair.wire._ import fr.acinq.eclair.{Globals, TestConstants, TestkitBaseClass, randomBytes32} -import org.scalatest.Outcome +import org.scalatest.{Outcome, Tag} import scodec.bits.ByteVector +import scala.compat.Platform import scala.concurrent.duration._ /** @@ -47,6 +49,40 @@ class ClosingStateSpec extends TestkitBaseClass with StateTestsHelperMethods { val setup = init() import setup._ + // NOTE + // As opposed to other tests, we won't reach the target state (here CLOSING) at the end of the fixture. + // The reason for this is that we may reach CLOSING state following several events: + // - local commit + // - remote commit + // - revoked commit + // and we want to be able to test the different scenarii. + // Hence the WAIT_FOR_FUNDING_CONFIRMED->CLOSING or NORMAL->CLOSING transition will occur in the individual tests. + + val unconfirmedFundingTx = test.tags.contains("funding_unconfirmed") + + if (unconfirmedFundingTx) { + within(30 seconds) { + val aliceInit = Init(Alice.channelParams.globalFeatures, Alice.channelParams.localFeatures) + val bobInit = Init(Bob.channelParams.globalFeatures, Bob.channelParams.localFeatures) + alice ! INPUT_INIT_FUNDER(ByteVector32.Zeroes, TestConstants.fundingSatoshis, TestConstants.pushMsat, TestConstants.feeratePerKw, TestConstants.feeratePerKw, Alice.channelParams, alice2bob.ref, bobInit, ChannelFlags.Empty) + bob ! INPUT_INIT_FUNDEE(ByteVector32.Zeroes, Bob.channelParams, bob2alice.ref, aliceInit) + alice2bob.expectMsgType[OpenChannel] + alice2bob.forward(bob) + bob2alice.expectMsgType[AcceptChannel] + bob2alice.forward(alice) + alice2bob.expectMsgType[FundingCreated] + alice2bob.forward(bob) + bob2alice.expectMsgType[FundingSigned] + bob2alice.forward(alice) + alice2blockchain.expectMsgType[WatchSpent] + alice2blockchain.expectMsgType[WatchConfirmed] + bob2blockchain.expectMsgType[WatchSpent] + bob2blockchain.expectMsgType[WatchConfirmed] + awaitCond(alice.stateName == WAIT_FOR_FUNDING_CONFIRMED) + awaitCond(bob.stateName == WAIT_FOR_FUNDING_CONFIRMED) + withFixture(test.toNoArgTest(FixtureParam(alice, bob, alice2bob, bob2alice, alice2blockchain, bob2blockchain, relayerA, relayerB, channelUpdateListener, Nil))) + } + } else { within(30 seconds) { reachNormal(setup) val bobCommitTxes: List[PublishableTxs] = (for (amt <- List(100000000, 200000000, 300000000)) yield { @@ -66,17 +102,9 @@ class ClosingStateSpec extends TestkitBaseClass with StateTestsHelperMethods { awaitCond(alice.stateName == NORMAL) awaitCond(bob.stateName == NORMAL) - - // NOTE - // As opposed to other tests, we won't reach the target state (here CLOSING) at the end of the fixture. - // The reason for this is that we may reach CLOSING state following several events: - // - local commit - // - remote commit - // - revoked commit - // and we want to be able to test the different scenarii. - // Hence the NORMAL->CLOSING transition will occur in the individual tests. withFixture(test.toNoArgTest(FixtureParam(alice, bob, alice2bob, bob2alice, alice2blockchain, bob2blockchain, relayerA, relayerB, channelUpdateListener, bobCommitTxes))) } + } } def mutualClose(alice: TestFSMRef[State, Data, Channel], @@ -109,6 +137,141 @@ class ClosingStateSpec extends TestkitBaseClass with StateTestsHelperMethods { // both nodes are now in CLOSING state with a mutual close tx pending for confirmation } + test("recv BITCOIN_FUNDING_PUBLISH_FAILED", Tag("funding_unconfirmed")) { f => + import f._ + alice ! CMD_FORCECLOSE + awaitCond(alice.stateName == CLOSING) + alice2blockchain.expectMsgType[PublishAsap] + alice2blockchain.expectMsgType[PublishAsap] // claim-main-delayed + + // test starts here + alice ! BITCOIN_FUNDING_PUBLISH_FAILED + alice2bob.expectMsgType[Error] + awaitCond(alice.stateName == CLOSED) + } + + test("recv BITCOIN_FUNDING_TIMEOUT", Tag("funding_unconfirmed")) { f => + import f._ + alice ! CMD_FORCECLOSE + awaitCond(alice.stateName == CLOSING) + alice2blockchain.expectMsgType[PublishAsap] + alice2blockchain.expectMsgType[PublishAsap] // claim-main-delayed + + // test starts here + alice ! BITCOIN_FUNDING_TIMEOUT + alice2bob.expectMsgType[Error] + awaitCond(alice.stateName == CLOSED) + } + + test("recv GetTxResponse (funder, tx found)", Tag("funding_unconfirmed")) { f => + import f._ + val fundingTx = alice.stateData.asInstanceOf[DATA_WAIT_FOR_FUNDING_CONFIRMED].fundingTx.get + alice ! CMD_FORCECLOSE + awaitCond(alice.stateName == CLOSING) + alice2bob.expectMsgType[Error] + alice2blockchain.expectMsgType[PublishAsap] + alice2blockchain.expectMsgType[PublishAsap] // claim-main-delayed + alice2blockchain.expectMsgType[WatchConfirmed] // commitment + alice2blockchain.expectMsgType[WatchConfirmed] // claim-main-delayed + + // test starts here + alice ! GetTxWithMetaResponse(fundingTx.txid, Some(fundingTx), Platform.currentTime.milliseconds.toSeconds) + alice2bob.expectNoMsg(200 millis) + alice2blockchain.expectNoMsg(200 millis) + assert(alice.stateName == CLOSING) // the above expectNoMsg will make us wait, so this checks that we are still in CLOSING + } + + test("recv GetTxResponse (funder, tx not found)", Tag("funding_unconfirmed")) { f => + import f._ + val fundingTx = alice.stateData.asInstanceOf[DATA_WAIT_FOR_FUNDING_CONFIRMED].fundingTx.get + alice ! CMD_FORCECLOSE + awaitCond(alice.stateName == CLOSING) + alice2bob.expectMsgType[Error] + alice2blockchain.expectMsgType[PublishAsap] + alice2blockchain.expectMsgType[PublishAsap] // claim-main-delayed + alice2blockchain.expectMsgType[WatchConfirmed] // commitment + alice2blockchain.expectMsgType[WatchConfirmed] // claim-main-delayed + + // test starts here + alice ! GetTxWithMetaResponse(fundingTx.txid, None, Platform.currentTime.milliseconds.toSeconds) + alice2bob.expectNoMsg(200 millis) + alice2blockchain.expectMsg(PublishAsap(fundingTx)) // we republish the funding tx + assert(alice.stateName == CLOSING) // the above expectNoMsg will make us wait, so this checks that we are still in CLOSING + } + + test("recv GetTxResponse (fundee, tx found)", Tag("funding_unconfirmed")) { f => + import f._ + val fundingTx = alice.stateData.asInstanceOf[DATA_WAIT_FOR_FUNDING_CONFIRMED].fundingTx.get + bob ! CMD_FORCECLOSE + awaitCond(bob.stateName == CLOSING) + bob2alice.expectMsgType[Error] + bob2blockchain.expectMsgType[PublishAsap] + bob2blockchain.expectMsgType[PublishAsap] // claim-main-delayed + bob2blockchain.expectMsgType[WatchConfirmed] // commitment + bob2blockchain.expectMsgType[WatchConfirmed] // claim-main-delayed + + // test starts here + bob ! GetTxWithMetaResponse(fundingTx.txid, Some(fundingTx), Platform.currentTime.milliseconds.toSeconds) + bob2alice.expectNoMsg(200 millis) + bob2blockchain.expectNoMsg(200 millis) + assert(bob.stateName == CLOSING) // the above expectNoMsg will make us wait, so this checks that we are still in CLOSING + } + + test("recv GetTxResponse (fundee, tx not found)", Tag("funding_unconfirmed")) { f => + import f._ + val fundingTx = alice.stateData.asInstanceOf[DATA_WAIT_FOR_FUNDING_CONFIRMED].fundingTx.get + bob ! CMD_FORCECLOSE + awaitCond(bob.stateName == CLOSING) + bob2alice.expectMsgType[Error] + bob2blockchain.expectMsgType[PublishAsap] + bob2blockchain.expectMsgType[PublishAsap] // claim-main-delayed + bob2blockchain.expectMsgType[WatchConfirmed] // commitment + bob2blockchain.expectMsgType[WatchConfirmed] // claim-main-delayed + + // test starts here + bob ! GetTxWithMetaResponse(fundingTx.txid, None, Platform.currentTime.milliseconds.toSeconds) + bob2alice.expectNoMsg(200 millis) + bob2blockchain.expectNoMsg(200 millis) + assert(bob.stateName == CLOSING) // the above expectNoMsg will make us wait, so this checks that we are still in CLOSING + } + + test("recv GetTxResponse (fundee, tx not found, timeout)", Tag("funding_unconfirmed")) { f => + import f._ + val fundingTx = alice.stateData.asInstanceOf[DATA_WAIT_FOR_FUNDING_CONFIRMED].fundingTx.get + bob ! CMD_FORCECLOSE + awaitCond(bob.stateName == CLOSING) + bob2alice.expectMsgType[Error] + bob2blockchain.expectMsgType[PublishAsap] + bob2blockchain.expectMsgType[PublishAsap] // claim-main-delayed + bob2blockchain.expectMsgType[WatchConfirmed] // commitment + bob2blockchain.expectMsgType[WatchConfirmed] // claim-main-delayed + + // test starts here + bob.setState(stateData = bob.stateData.asInstanceOf[DATA_CLOSING].copy(waitingSince = Platform.currentTime.milliseconds.toSeconds - 15.days.toSeconds)) + bob ! GetTxWithMetaResponse(fundingTx.txid, None, Platform.currentTime.milliseconds.toSeconds) + bob2alice.expectMsgType[Error] + bob2blockchain.expectNoMsg(200 millis) + assert(bob.stateName == CLOSED) + } + + test("recv GetTxResponse (fundee, tx not found, timeout, blockchain lags)", Tag("funding_unconfirmed")) { f => + import f._ + val fundingTx = alice.stateData.asInstanceOf[DATA_WAIT_FOR_FUNDING_CONFIRMED].fundingTx.get + bob ! CMD_FORCECLOSE + awaitCond(bob.stateName == CLOSING) + bob2alice.expectMsgType[Error] + bob2blockchain.expectMsgType[PublishAsap] + bob2blockchain.expectMsgType[PublishAsap] // claim-main-delayed + bob2blockchain.expectMsgType[WatchConfirmed] // commitment + bob2blockchain.expectMsgType[WatchConfirmed] // claim-main-delayed + + // test starts here + bob ! GetTxWithMetaResponse(fundingTx.txid, None, Platform.currentTime.milliseconds.toSeconds - 3.hours.toSeconds) + bob2alice.expectNoMsg(200 millis) + bob2blockchain.expectNoMsg(200 millis) + assert(bob.stateName == CLOSING) // the above expectNoMsg will make us wait, so this checks that we are still in CLOSING + } + test("recv CMD_ADD_HTLC") { f => import f._ mutualClose(alice, bob, alice2bob, bob2alice, alice2blockchain, bob2blockchain) @@ -159,7 +322,7 @@ class ClosingStateSpec extends TestkitBaseClass with StateTestsHelperMethods { // actual test starts here alice ! WatchEventSpent(BITCOIN_FUNDING_SPENT, mutualCloseTx) - alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(mutualCloseTx), 0, 0) + alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(mutualCloseTx), 0, 0, mutualCloseTx) awaitCond(alice.stateName == CLOSED) } @@ -169,7 +332,7 @@ class ClosingStateSpec extends TestkitBaseClass with StateTestsHelperMethods { val mutualCloseTx = alice.stateData.asInstanceOf[DATA_CLOSING].mutualClosePublished.last // actual test starts here - alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(mutualCloseTx), 0, 0) + alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(mutualCloseTx), 0, 0, mutualCloseTx) awaitCond(alice.stateName == CLOSED) } @@ -252,12 +415,12 @@ class ClosingStateSpec extends TestkitBaseClass with StateTestsHelperMethods { assert(initialState.localCommitPublished.isDefined) // actual test starts here - alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(aliceCommitTx), 42, 0) + alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(aliceCommitTx), 42, 0, aliceCommitTx) assert(listener.expectMsgType[LocalCommitConfirmed].refundAtBlock == 42 + TestConstants.Bob.channelParams.toSelfDelay) assert(listener.expectMsgType[PaymentSettlingOnChain].paymentHash == htlca1.paymentHash) - alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(claimMainDelayedTx), 200, 0) - alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(htlcTimeoutTx), 201, 0) - alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(claimDelayedTx), 202, 0) + alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(claimMainDelayedTx), 200, 0, claimMainDelayedTx) + alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(htlcTimeoutTx), 201, 0, htlcTimeoutTx) + alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(claimDelayedTx), 202, 0, claimDelayedTx) awaitCond(alice.stateName == CLOSED) } @@ -284,7 +447,7 @@ class ClosingStateSpec extends TestkitBaseClass with StateTestsHelperMethods { // actual test starts here // when the commit tx is signed, alice knows that the htlc she sent right before the unilateral close will never reach the chain - alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(aliceCommitTx), 0, 0) + alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(aliceCommitTx), 0, 0, aliceCommitTx) // so she fails it val origin = alice.stateData.asInstanceOf[DATA_CLOSING].commitments.originChannels(htlc.id) relayerA.expectMsg(Status.Failure(AddHtlcFailed(aliceData.channelId, htlc.paymentHash, HtlcOverridenByLocalCommit(aliceData.channelId), origin, None, None))) @@ -313,7 +476,7 @@ class ClosingStateSpec extends TestkitBaseClass with StateTestsHelperMethods { // actual test starts here // when the commit tx is signed, alice knows that the htlc she sent right before the unilateral close will never reach the chain - alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(bobCommitTx), 0, 0) + alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(bobCommitTx), 0, 0, bobCommitTx) // so she fails it val origin = alice.stateData.asInstanceOf[DATA_CLOSING].commitments.originChannels(htlc.id) relayerA.expectMsg(Status.Failure(AddHtlcFailed(aliceData.channelId, htlc.paymentHash, HtlcOverridenByLocalCommit(aliceData.channelId), origin, None, None))) @@ -351,8 +514,8 @@ class ClosingStateSpec extends TestkitBaseClass with StateTestsHelperMethods { assert(alice.stateData.asInstanceOf[DATA_CLOSING].copy(remoteCommitPublished = None) == initialState) // actual test starts here - alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(bobCommitTx), 0, 0) - alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(claimMainTx), 0, 0) + alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(bobCommitTx), 0, 0, bobCommitTx) + alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(claimMainTx), 0, 0, claimMainTx) awaitCond(alice.stateName == CLOSED) } @@ -396,8 +559,8 @@ class ClosingStateSpec extends TestkitBaseClass with StateTestsHelperMethods { awaitCond(alice.stateData.asInstanceOf[DATA_CLOSING].futureRemoteCommitPublished.isDefined) // actual test starts here - alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(bobCommitTx), 0, 0) - alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(claimMainTx), 0, 0) + alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(bobCommitTx), 0, 0, bobCommitTx) + alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(claimMainTx), 0, 0, claimMainTx) awaitCond(alice.stateName == CLOSED) } @@ -479,17 +642,17 @@ class ClosingStateSpec extends TestkitBaseClass with StateTestsHelperMethods { awaitCond(alice.stateData.asInstanceOf[DATA_CLOSING].revokedCommitPublished.head.commitTx == bobRevokedTx.commitTx.tx) // actual test starts here - alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(bobRevokedTx.commitTx.tx), 0, 0) - alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(claimMainTx), 0, 0) - alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(mainPenaltyTx), 0, 0) + alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(bobRevokedTx.commitTx.tx), 0, 0, bobRevokedTx.commitTx.tx) + alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(claimMainTx), 0, 0, claimMainTx) + alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(mainPenaltyTx), 0, 0, mainPenaltyTx) alice ! WatchEventSpent(BITCOIN_OUTPUT_SPENT, htlcPenaltyTx) // we published this alice2blockchain.expectMsgType[WatchConfirmed] // htlc-penalty val bobHtlcSuccessTx = bobRevokedTx.htlcTxsAndSigs.head.txinfo.tx alice ! WatchEventSpent(BITCOIN_OUTPUT_SPENT, bobHtlcSuccessTx) // bob published his HtlcSuccess tx alice2blockchain.expectMsgType[WatchConfirmed] // htlc-success val claimHtlcDelayedPenaltyTxs = alice2blockchain.expectMsgType[PublishAsap].tx // we publish a tx spending the output of bob's HtlcSuccess tx - alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(bobHtlcSuccessTx), 0, 0) // bob won - alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(claimHtlcDelayedPenaltyTxs), 0, 0) // bob won + alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(bobHtlcSuccessTx), 0, 0, bobHtlcSuccessTx) // bob won + alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(claimHtlcDelayedPenaltyTxs), 0, 0, claimHtlcDelayedPenaltyTxs) // bob won awaitCond(alice.stateName == CLOSED) } @@ -511,11 +674,11 @@ class ClosingStateSpec extends TestkitBaseClass with StateTestsHelperMethods { awaitCond(alice.stateData.asInstanceOf[DATA_CLOSING].revokedCommitPublished.head.commitTx == bobRevokedTx.commitTx.tx) // actual test starts here - alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(bobRevokedTx.commitTx.tx), 0, 0) - alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(claimMainTx), 0, 0) - alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(mainPenaltyTx), 0, 0) + alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(bobRevokedTx.commitTx.tx), 0, 0, bobRevokedTx.commitTx.tx) + alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(claimMainTx), 0, 0, claimMainTx) + alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(mainPenaltyTx), 0, 0, mainPenaltyTx) alice ! WatchEventSpent(BITCOIN_OUTPUT_SPENT, htlcPenaltyTx) - alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(htlcPenaltyTx), 0, 0) + alice ! WatchEventConfirmed(BITCOIN_TX_CONFIRMED(htlcPenaltyTx), 0, 0, htlcPenaltyTx) awaitCond(alice.stateName == CLOSED) } diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/interop/rustytests/RustyTestsSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/interop/rustytests/RustyTestsSpec.scala index 94e940a5d8..2e15d4ce78 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/interop/rustytests/RustyTestsSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/interop/rustytests/RustyTestsSpec.scala @@ -67,8 +67,10 @@ class RustyTestsSpec extends TestKit(ActorSystem("test")) with Matchers with fix alice2blockchain.expectMsgType[WatchConfirmed] bob2blockchain.expectMsgType[WatchSpent] bob2blockchain.expectMsgType[WatchConfirmed] - alice ! WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK, 400000, 42) - bob ! WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK, 400000, 42) + awaitCond(alice.stateName == WAIT_FOR_FUNDING_CONFIRMED) + val fundingTx = alice.stateData.asInstanceOf[DATA_WAIT_FOR_FUNDING_CONFIRMED].fundingTx.get + alice ! WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK, 400000, 42, fundingTx) + bob ! WatchEventConfirmed(BITCOIN_FUNDING_DEPTHOK, 400000, 42, fundingTx) alice2blockchain.expectMsgType[WatchLost] bob2blockchain.expectMsgType[WatchLost] awaitCond(alice.stateName == NORMAL) From 32145e8d6a619a93d54124c1be3f69023485e19b Mon Sep 17 00:00:00 2001 From: Pierre-Marie Padiou Date: Wed, 3 Jul 2019 13:15:20 +0200 Subject: [PATCH 03/12] Connect immediately on restart, then wait (#1040) * connect immediately on restart, then wait This is to allow herd effect when we restart the app and have numerous peers. Also removed the unnecessary transition and cleaned up delay computation. * always reconnect immediately when disconnected Whether we go to this state from startup, or after getting disconnected. It makes the transition logic simpler, and the potential herd effect at startup is inevitable anyway since our peers will try to reconnect too. * add randomization when reconnecting * randomize delay for first reconnection attempt after startup * make some parameters configurable --- eclair-core/src/main/resources/reference.conf | 2 + .../scala/fr/acinq/eclair/NodeParams.scala | 6 +- .../fr/acinq/eclair/channel/Channel.scala | 2 +- .../main/scala/fr/acinq/eclair/io/Peer.scala | 39 ++++++-- .../fr/acinq/eclair/io/Switchboard.scala | 13 +-- .../scala/fr/acinq/eclair/TestConstants.scala | 4 + .../channel/states/e/NormalStateSpec.scala | 2 +- .../scala/fr/acinq/eclair/io/PeerSpec.scala | 54 +++++++++-- .../acinq/eclair/io/PeerSpecWithLogging.scala | 44 --------- .../fr/acinq/eclair/io/SwitchboardSpec.scala | 95 +++++++++++++++++++ 10 files changed, 185 insertions(+), 76 deletions(-) delete mode 100644 eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpecWithLogging.scala create mode 100644 eclair-core/src/test/scala/fr/acinq/eclair/io/SwitchboardSpec.scala diff --git a/eclair-core/src/main/resources/reference.conf b/eclair-core/src/main/resources/reference.conf index e8764cf7c3..b2de25ee7c 100644 --- a/eclair-core/src/main/resources/reference.conf +++ b/eclair-core/src/main/resources/reference.conf @@ -86,6 +86,8 @@ eclair { ping-timeout = 10 seconds // will disconnect if peer takes longer than that to respond ping-disconnect = true // disconnect if no answer to our pings auto-reconnect = true + initial-random-reconnect-delay = 5 seconds // we add a random delay before the first reconnection attempt, capped by this value + max-reconnect-interval = 1 hour // max interval between two reconnection attempts, after the exponential backoff period payment-handler = "local" payment-request-expiry = 1 hour // default expiry for payment requests generated by this node diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala b/eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala index c5977a4816..9266d701e7 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala @@ -19,7 +19,6 @@ package fr.acinq.eclair import java.io.File import java.net.InetSocketAddress import java.nio.file.Files -import java.sql.DriverManager import java.util.concurrent.TimeUnit import com.typesafe.config.{Config, ConfigFactory} @@ -29,7 +28,6 @@ import fr.acinq.eclair.NodeParams.WatcherType import fr.acinq.eclair.channel.Channel import fr.acinq.eclair.crypto.KeyManager import fr.acinq.eclair.db._ -import fr.acinq.eclair.db.sqlite._ import fr.acinq.eclair.router.RouterConf import fr.acinq.eclair.tor.Socks5ProxyParams import fr.acinq.eclair.wire.{Color, NodeAddress} @@ -69,6 +67,8 @@ case class NodeParams(keyManager: KeyManager, maxFeerateMismatch: Double, updateFeeMinDiffRatio: Double, autoReconnect: Boolean, + initialRandomReconnectDelay: FiniteDuration, + maxReconnectInterval: FiniteDuration, chainHash: ByteVector32, channelFlags: Byte, watcherType: WatcherType, @@ -205,6 +205,8 @@ object NodeParams { maxFeerateMismatch = config.getDouble("max-feerate-mismatch"), updateFeeMinDiffRatio = config.getDouble("update-fee_min-diff-ratio"), autoReconnect = config.getBoolean("auto-reconnect"), + initialRandomReconnectDelay = FiniteDuration(config.getDuration("initial-random-reconnect-delay").getSeconds, TimeUnit.SECONDS), + maxReconnectInterval = FiniteDuration(config.getDuration("max-reconnect-interval").getSeconds, TimeUnit.SECONDS), chainHash = chainHash, channelFlags = config.getInt("channel-flags").toByte, watcherType = watcherType, diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/Channel.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/Channel.scala index a4e4c9b0e9..8f71a13f53 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/Channel.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/Channel.scala @@ -1813,7 +1813,7 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId d.commitments.remoteNextCommitInfo match { case Left(waitingForRevocation) if revocationTimeout.remoteCommitNumber + 1 == waitingForRevocation.nextRemoteCommit.index => log.warning(s"waited for too long for a revocation to remoteCommitNumber=${revocationTimeout.remoteCommitNumber}, disconnecting") - revocationTimeout.peer ! Peer.Disconnect + revocationTimeout.peer ! Peer.Disconnect(remoteNodeId) case _ => () } stay diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/io/Peer.scala b/eclair-core/src/main/scala/fr/acinq/eclair/io/Peer.scala index 43dcb4903c..08969aed8d 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/io/Peer.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/io/Peer.scala @@ -34,6 +34,7 @@ import fr.acinq.eclair.wire._ import fr.acinq.eclair.{secureRandom, wire, _} import scodec.Attempt import scodec.bits.ByteVector + import scala.compat.Platform import scala.concurrent.duration._ import scala.util.Random @@ -41,7 +42,7 @@ import scala.util.Random /** * Created by PM on 26/08/2016. */ -class Peer(nodeParams: NodeParams, remoteNodeId: PublicKey, authenticator: ActorRef, watcher: ActorRef, router: ActorRef, relayer: ActorRef, wallet: EclairWallet) extends FSMDiagnosticActorLogging[Peer.State, Peer.Data] { +class Peer(val nodeParams: NodeParams, remoteNodeId: PublicKey, authenticator: ActorRef, watcher: ActorRef, router: ActorRef, relayer: ActorRef, wallet: EclairWallet) extends FSMDiagnosticActorLogging[Peer.State, Peer.Data] { import Peer._ @@ -54,7 +55,13 @@ class Peer(nodeParams: NodeParams, remoteNodeId: PublicKey, authenticator: Actor channel ! INPUT_RESTORED(state) FinalChannelId(state.channelId) -> channel }.toMap - goto(DISCONNECTED) using DisconnectedData(previousKnownAddress, channels) + // When restarting, we will immediately reconnect, but then: + // - we don't want all the subsequent reconnection attempts to be synchronized (herd effect) + // - we don't want to go through the exponential backoff delay, because we were offline, not them, so there is no + // reason to eagerly retry + // That's why we set the next reconnection delay to a random value between MAX_RECONNECT_INTERVAL/2 and MAX_RECONNECT_INTERVAL. + val firstNextReconnectionDelay = nodeParams.maxReconnectInterval.minus(Random.nextInt(nodeParams.maxReconnectInterval.toSeconds.toInt / 2).seconds) + goto(DISCONNECTED) using DisconnectedData(previousKnownAddress, channels, firstNextReconnectionDelay) // when we restart, we will attempt to reconnect right away, but then we'll wait } when(DISCONNECTED) { @@ -80,13 +87,12 @@ class Peer(nodeParams: NodeParams, remoteNodeId: PublicKey, authenticator: Actor case Event(Reconnect, d: DisconnectedData) => d.address_opt.orElse(getPeerAddressFromNodeAnnouncement) match { case _ if d.channels.isEmpty => stay // no-op, no more channels with this peer - case None => stay // no-op, we don't know any address to this peer and we won't try reconnecting again + case None => stay // no-op, we don't know any address to this peer and we won't try reconnecting again case Some(address) => context.actorOf(Client.props(nodeParams, authenticator, address, remoteNodeId, origin_opt = None)) - log.info(s"reconnecting to $address") - // exponential backoff retry with a finite max - setTimer(RECONNECT_TIMER, Reconnect, Math.min(10 + Math.pow(2, d.attempts), 3600) seconds, repeat = false) - stay using d.copy(attempts = d.attempts + 1) + log.info(s"reconnecting to $address (next reconnection in ${d.nextReconnectionDelay.toSeconds} seconds)") + setTimer(RECONNECT_TIMER, Reconnect, d.nextReconnectionDelay, repeat = false) + stay using d.copy(nextReconnectionDelay = nextReconnectionDelay(d.nextReconnectionDelay, nodeParams.maxReconnectInterval)) } case Event(Authenticator.Authenticated(_, transport, remoteNodeId1, address, outgoing, origin_opt), d: DisconnectedData) => @@ -503,9 +509,17 @@ class Peer(nodeParams: NodeParams, remoteNodeId: PublicKey, authenticator: Actor case Event(_: BadMessage, _) => stay // we got disconnected while syncing } + /** + * The transition INSTANTIATING -> DISCONNECTED happens in 2 scenarios + * - Manual connection to a new peer: then when(DISCONNECTED) we expect a Peer.Connect from the switchboard + * - Eclair restart: The switchboard creates the peers and sends Init and then Peer.Reconnect to trigger reconnection attempts + * + * So when we see this transition we NO-OP because we don't want to start a Reconnect timer but the peer will receive the trigger + * (Connect/Reconnect) messages from the switchboard. + */ onTransition { - case INSTANTIATING -> DISCONNECTED if nodeParams.autoReconnect && nextStateData.address_opt.isDefined => self ! Reconnect // we reconnect right away if we just started the peer - case _ -> DISCONNECTED if nodeParams.autoReconnect => setTimer(RECONNECT_TIMER, Reconnect, 1 second, repeat = false) + case INSTANTIATING -> DISCONNECTED => () + case _ -> DISCONNECTED if nodeParams.autoReconnect => setTimer(RECONNECT_TIMER, Reconnect, Random.nextInt(nodeParams.initialRandomReconnectDelay.toMillis.toInt).millis, repeat = false) // we add some randomization to not have peers reconnect to each other exactly at the same time case DISCONNECTED -> _ if nodeParams.autoReconnect => cancelTimer(RECONNECT_TIMER) } @@ -568,7 +582,7 @@ object Peer { def channels: Map[_ <: ChannelId, ActorRef] // will be overridden by Map[FinalChannelId, ActorRef] or Map[ChannelId, ActorRef] } case class Nothing() extends Data { override def address_opt = None; override def channels = Map.empty } - case class DisconnectedData(address_opt: Option[InetSocketAddress], channels: Map[FinalChannelId, ActorRef], attempts: Int = 0) extends Data + case class DisconnectedData(address_opt: Option[InetSocketAddress], channels: Map[FinalChannelId, ActorRef], nextReconnectionDelay: FiniteDuration = 10 seconds) extends Data case class InitializingData(address_opt: Option[InetSocketAddress], transport: ActorRef, channels: Map[FinalChannelId, ActorRef], origin_opt: Option[ActorRef], localInit: wire.Init) extends Data case class ConnectedData(address_opt: Option[InetSocketAddress], transport: ActorRef, localInit: wire.Init, remoteInit: wire.Init, channels: Map[ChannelId, ActorRef], rebroadcastDelay: FiniteDuration, gossipTimestampFilter: Option[GossipTimestampFilter] = None, behavior: Behavior = Behavior(), expectedPong_opt: Option[ExpectedPong] = None) extends Data case class ExpectedPong(ping: Ping, timestamp: Long = Platform.currentTime) @@ -656,4 +670,9 @@ object Peer { } def hostAndPort2InetSocketAddress(hostAndPort: HostAndPort): InetSocketAddress = new InetSocketAddress(hostAndPort.getHost, hostAndPort.getPort) + + /** + * Exponential backoff retry with a finite max + */ + def nextReconnectionDelay(currentDelay: FiniteDuration, maxReconnectInterval: FiniteDuration): FiniteDuration = (2 * currentDelay).min(maxReconnectInterval) } diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/io/Switchboard.scala b/eclair-core/src/main/scala/fr/acinq/eclair/io/Switchboard.scala index 33bb050711..5ba608af54 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/io/Switchboard.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/io/Switchboard.scala @@ -69,17 +69,14 @@ class Switchboard(nodeParams: NodeParams, authenticator: ActorRef, watcher: Acto channels .groupBy(_.commitments.remoteParams.nodeId) .map { - case (remoteNodeId, states) => - val address_opt = peers.get(remoteNodeId).orElse { - nodeParams.db.network.getNode(remoteNodeId).flatMap(_.addresses.headOption) // gets the first of the list! TODO improve selection? - } - (remoteNodeId, states, address_opt) + case (remoteNodeId, states) => (remoteNodeId, states, peers.get(remoteNodeId)) } .foreach { case (remoteNodeId, states, nodeaddress_opt) => // we might not have an address if we didn't initiate the connection in the first place val address_opt = nodeaddress_opt.map(_.socketAddress) - createOrGetPeer(remoteNodeId, previousKnownAddress = address_opt, offlineChannels = states.toSet) + val peer = createOrGetPeer(remoteNodeId, previousKnownAddress = address_opt, offlineChannels = states.toSet) + peer ! Peer.Reconnect } } @@ -116,8 +113,6 @@ class Switchboard(nodeParams: NodeParams, authenticator: ActorRef, watcher: Acto } - def peerActorName(remoteNodeId: PublicKey): String = s"peer-$remoteNodeId" - /** * Retrieves a peer based on its public key. * @@ -159,6 +154,8 @@ object Switchboard extends Logging { def props(nodeParams: NodeParams, authenticator: ActorRef, watcher: ActorRef, router: ActorRef, relayer: ActorRef, wallet: EclairWallet) = Props(new Switchboard(nodeParams, authenticator, watcher, router, relayer, wallet)) + def peerActorName(remoteNodeId: PublicKey): String = s"peer-$remoteNodeId" + /** * If we have stopped eclair while it was forwarding HTLCs, it is possible that we are in a state were an incoming HTLC * was committed by both sides, but we didn't have time to send and/or sign the corresponding HTLC to the downstream node. diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/TestConstants.scala b/eclair-core/src/test/scala/fr/acinq/eclair/TestConstants.scala index b2a3272239..79770b5833 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/TestConstants.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/TestConstants.scala @@ -77,6 +77,8 @@ object TestConstants { maxFeerateMismatch = 1.5, updateFeeMinDiffRatio = 0.1, autoReconnect = false, + initialRandomReconnectDelay = 5 seconds, + maxReconnectInterval = 1 hour, chainHash = Block.RegtestGenesisBlock.hash, channelFlags = 1, watcherType = BITCOIND, @@ -141,6 +143,8 @@ object TestConstants { maxFeerateMismatch = 1.0, updateFeeMinDiffRatio = 0.1, autoReconnect = false, + initialRandomReconnectDelay = 5 seconds, + maxReconnectInterval = 1 hour, chainHash = Block.RegtestGenesisBlock.hash, channelFlags = 1, watcherType = BITCOIND, diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/e/NormalStateSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/e/NormalStateSpec.scala index 768583a3d4..b37eb9418b 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/e/NormalStateSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/states/e/NormalStateSpec.scala @@ -1003,7 +1003,7 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods { awaitCond(alice.stateData.asInstanceOf[DATA_NORMAL].commitments.remoteNextCommitInfo.isLeft) val peer = TestProbe() sender.send(alice, RevocationTimeout(alice.stateData.asInstanceOf[DATA_NORMAL].commitments.remoteCommit.index, peer.ref)) - peer.expectMsg(Peer.Disconnect) + peer.expectMsg(Peer.Disconnect(alice.stateData.asInstanceOf[DATA_NORMAL].commitments.remoteParams.nodeId)) } test("recv CMD_FULFILL_HTLC") { f => diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala index 87ff5c0785..51969071f3 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala @@ -18,9 +18,11 @@ package fr.acinq.eclair.io import java.net.{Inet4Address, InetSocketAddress} +import akka.actor.{ActorRef, PoisonPill, Terminated} +import java.net.{Inet4Address, InetAddress, InetSocketAddress, ServerSocket} import akka.actor.{ActorRef, ActorSystem, PoisonPill} import akka.actor.FSM.{CurrentState, SubscribeTransitionCallBack, Transition} -import akka.testkit.{EventFilter, TestFSMRef, TestKit, TestProbe} +import akka.testkit.{TestFSMRef, TestProbe} import fr.acinq.bitcoin.Crypto.PublicKey import fr.acinq.eclair.TestConstants._ import fr.acinq.eclair._ @@ -34,7 +36,6 @@ import fr.acinq.eclair.router.{ChannelRangeQueries, ChannelRangeQueriesSpec, Reb import fr.acinq.eclair.wire.{Color, Error, IPv4, NodeAddress, NodeAnnouncement, Ping, Pong} import org.scalatest.{Outcome, Tag} import scodec.bits.ByteVector - import scala.concurrent.duration._ class PeerSpec extends TestkitBaseClass { @@ -54,8 +55,8 @@ class PeerSpec extends TestkitBaseClass { val aParams = Alice.nodeParams val aliceParams = test.tags.contains("with_node_announcements") match { case true => - val aliceAnnouncement = NodeAnnouncement(randomBytes64, ByteVector.empty, 1, Bob.nodeParams.nodeId, Color(100.toByte, 200.toByte, 300.toByte), "node-alias", fakeIPAddress :: Nil) - aParams.db.network.addNode(aliceAnnouncement) + val bobAnnouncement = NodeAnnouncement(randomBytes64, ByteVector.empty, 1, Bob.nodeParams.nodeId, Color(100.toByte, 200.toByte, 300.toByte), "node-alias", fakeIPAddress :: Nil) + aParams.db.network.addNode(bobAnnouncement) aParams case false => aParams } @@ -151,17 +152,50 @@ class PeerSpec extends TestkitBaseClass { probe.expectNoMsg() } - test("count reconnections") { f => + test("reconnect using the address from node_announcement") { f => + import f._ + + // we create a dummy tcp server and update bob's announcement to point to it + val mockServer = new ServerSocket(0, 1, InetAddress.getLocalHost) // port will be assigned automatically + val mockAddress = NodeAddress.fromParts(mockServer.getInetAddress.getHostAddress, mockServer.getLocalPort).get + val bobAnnouncement = NodeAnnouncement(randomBytes64, ByteVector.empty, 1, Bob.nodeParams.nodeId, Color(100.toByte, 200.toByte, 300.toByte), "node-alias", mockAddress :: Nil) + peer.underlyingActor.nodeParams.db.network.addNode(bobAnnouncement) + + val probe = TestProbe() + awaitCond(peer.stateName == INSTANTIATING) + probe.send(peer, Peer.Init(None, Set(ChannelStateSpec.normal))) + awaitCond(peer.stateName == DISCONNECTED) + + // we have auto-reconnect=false so we need to manually tell the peer to reconnect + probe.send(peer, Reconnect) + + // assert our mock server got an incoming connection (the client was spawned with the address from node_announcement) + within(30 seconds) { + mockServer.accept() + } + } + + test("only reconnect once with a randomized delay after startup") { f => import f._ val probe = TestProbe() val previouslyKnownAddress = new InetSocketAddress("1.2.3.4", 9735) probe.send(peer, Peer.Init(Some(previouslyKnownAddress), Set(ChannelStateSpec.normal))) probe.send(peer, Peer.Reconnect) - awaitCond(peer.stateData.asInstanceOf[DisconnectedData].attempts == 1) - probe.send(peer, Peer.Reconnect) - awaitCond(peer.stateData.asInstanceOf[DisconnectedData].attempts == 2) - probe.send(peer, Peer.Reconnect) - awaitCond(peer.stateData.asInstanceOf[DisconnectedData].attempts == 3) + val interval = (peer.underlyingActor.nodeParams.maxReconnectInterval.toSeconds / 2) to peer.underlyingActor.nodeParams.maxReconnectInterval.toSeconds + awaitCond(interval contains peer.stateData.asInstanceOf[DisconnectedData].nextReconnectionDelay.toSeconds) + } + + test("reconnect with increasing delays") { f => + import f._ + val probe = TestProbe() + connect(remoteNodeId, authenticator, watcher, router, relayer, connection, transport, peer, channels = Set(ChannelStateSpec.normal)) + probe.send(transport.ref, PoisonPill) + awaitCond(peer.stateName === DISCONNECTED) + assert(peer.stateData.asInstanceOf[DisconnectedData].nextReconnectionDelay === (10 seconds)) + probe.send(peer, Reconnect) + assert(peer.stateData.asInstanceOf[DisconnectedData].nextReconnectionDelay === (20 seconds)) + probe.send(peer, Reconnect) + assert(peer.stateData.asInstanceOf[DisconnectedData].nextReconnectionDelay === (40 seconds)) } test("disconnect if incompatible features") { f => diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpecWithLogging.scala b/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpecWithLogging.scala deleted file mode 100644 index 7a3e02a6c7..0000000000 --- a/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpecWithLogging.scala +++ /dev/null @@ -1,44 +0,0 @@ -package fr.acinq.eclair.io - -import akka.actor.{ActorRef, ActorSystem} -import akka.testkit.{EventFilter, TestFSMRef, TestKit, TestProbe} -import com.typesafe.config.ConfigFactory -import fr.acinq.eclair.db.ChannelStateSpec -import org.scalatest.{FunSuiteLike, Outcome, Tag} - -import scala.concurrent.duration._ -import akka.testkit.{TestFSMRef, TestProbe} -import fr.acinq.eclair.TestConstants.{Alice, Bob} -import fr.acinq.eclair.blockchain.EclairWallet -import fr.acinq.eclair.randomBytes64 -import fr.acinq.eclair.wire.{Color, IPv4, NodeAddress, NodeAnnouncement} -import scodec.bits.ByteVector - -class PeerSpecWithLogging extends TestKit(ActorSystem("test", ConfigFactory.parseString("""akka.loggers = ["akka.testkit.TestEventListener"]"""))) with FunSuiteLike { - - val fakeIPAddress = NodeAddress.fromParts("1.2.3.4", 42000).get - - test("reconnect using the address from node_announcement") { - val aliceParams = Alice.nodeParams - val aliceAnnouncement = NodeAnnouncement(randomBytes64, ByteVector.empty, 1, Bob.nodeParams.nodeId, Color(100.toByte, 200.toByte, 300.toByte), "node-alias", fakeIPAddress :: Nil) - aliceParams.db.network.addNode(aliceAnnouncement) - val authenticator = TestProbe() - val watcher = TestProbe() - val router = TestProbe() - val relayer = TestProbe() - val wallet: EclairWallet = null // unused - val remoteNodeId = Bob.nodeParams.nodeId - val peer: TestFSMRef[Peer.State, Peer.Data, Peer] = TestFSMRef(new Peer(aliceParams, remoteNodeId, authenticator.ref, watcher.ref, router.ref, relayer.ref, wallet)) - - - val probe = TestProbe() - awaitCond({peer.stateName.toString == "INSTANTIATING"}, 10 seconds) - probe.send(peer, Peer.Init(None, Set(ChannelStateSpec.normal))) - awaitCond({peer.stateName.toString == "DISCONNECTED" && peer.stateData.address_opt.isEmpty}, 10 seconds) - EventFilter.info(message = s"reconnecting to ${fakeIPAddress.socketAddress}", occurrences = 1) intercept { - probe.send(peer, Peer.Reconnect) - } - } - - -} diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/io/SwitchboardSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/io/SwitchboardSpec.scala new file mode 100644 index 0000000000..0af0579f40 --- /dev/null +++ b/eclair-core/src/test/scala/fr/acinq/eclair/io/SwitchboardSpec.scala @@ -0,0 +1,95 @@ +package fr.acinq.eclair.io + +import java.io.File + +import akka.actor.{ActorRef, ActorSystem, Props} +import akka.testkit.{TestKit, TestProbe} +import fr.acinq.bitcoin.ByteVector64 +import fr.acinq.bitcoin.Crypto.PublicKey +import fr.acinq.eclair.TestConstants._ +import fr.acinq.eclair.blockchain.TestWallet +import fr.acinq.eclair.db._ +import fr.acinq.eclair.wire.{Color, NodeAddress, NodeAnnouncement} +import org.mockito.scalatest.IdiomaticMockito +import org.scalatest.FunSuiteLike +import scodec.bits._ + +class SwitchboardSpec extends TestKit(ActorSystem("test")) with FunSuiteLike with IdiomaticMockito { + + test("on initialization create peers and send Reconnect to them") { + + val mockNetworkDb = mock[NetworkDb] + val nodeParams = Alice.nodeParams.copy( + db = new Databases { + override val network: NetworkDb = mockNetworkDb + override val audit: AuditDb = Alice.nodeParams.db.audit + override val channels: ChannelsDb = Alice.nodeParams.db.channels + override val peers: PeersDb = Alice.nodeParams.db.peers + override val payments: PaymentsDb = Alice.nodeParams.db.payments + override val pendingRelay: PendingRelayDb = Alice.nodeParams.db.pendingRelay + override def backup(file: File): Unit = () + } + ) + + val remoteNodeId = ChannelStateSpec.normal.commitments.remoteParams.nodeId + val authenticator = TestProbe() + val watcher = TestProbe() + val router = TestProbe() + val relayer = TestProbe() + val wallet = new TestWallet() + val probe = TestProbe() + + // mock the call that will be done by the peer once it receives Peer.Reconnect + mockNetworkDb.getNode(remoteNodeId) returns Some( + NodeAnnouncement(ByteVector64.Zeroes, ByteVector.empty, 0, remoteNodeId, Color(0,0,0), "alias", List(NodeAddress.fromParts("127.0.0.1", 9735).get)) + ) + + // add a channel to the db + nodeParams.db.channels.addOrUpdateChannel(ChannelStateSpec.normal) + + val switchboard = system.actorOf(Switchboard.props(nodeParams, authenticator.ref, watcher.ref, router.ref, relayer.ref, wallet)) + + probe.send(switchboard, 'peers) + val List(peer) = probe.expectMsgType[Iterable[ActorRef]].toList + assert(peer.path.name == Switchboard.peerActorName(remoteNodeId)) + + // assert that the peer called `networkDb.getNode` - because it received a Peer.Reconnect + awaitAssert(mockNetworkDb.getNode(remoteNodeId).wasCalled(once)) + } + + test("when connecting to a new peer forward Peer.Connect to it") { + val mockNetworkDb = mock[NetworkDb] + val nodeParams = Alice.nodeParams.copy( + db = new Databases { + override val network: NetworkDb = mockNetworkDb + override val audit: AuditDb = Alice.nodeParams.db.audit + override val channels: ChannelsDb = Alice.nodeParams.db.channels + override val peers: PeersDb = Alice.nodeParams.db.peers + override val payments: PaymentsDb = Alice.nodeParams.db.payments + override val pendingRelay: PendingRelayDb = Alice.nodeParams.db.pendingRelay + override def backup(file: File): Unit = () + } + ) + + val remoteNodeId = PublicKey(hex"03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f") + val authenticator = TestProbe() + val watcher = TestProbe() + val router = TestProbe() + val relayer = TestProbe() + val wallet = new TestWallet() + val probe = TestProbe() + + // mock the call that will be done by the peer once it receives Peer.Connect(remoteNodeId) + mockNetworkDb.getNode(remoteNodeId) returns Some( + NodeAnnouncement(ByteVector64.Zeroes, ByteVector.empty, 0, remoteNodeId, Color(0,0,0), "alias", List(NodeAddress.fromParts("127.0.0.1", 9735).get)) + ) + + val switchboard = system.actorOf(Switchboard.props(nodeParams, authenticator.ref, watcher.ref, router.ref, relayer.ref, wallet)) + + // send Peer.Connect to switchboard, it will forward to the Peer and the peer will look up the address on the db + probe.send(switchboard, Peer.Connect(remoteNodeId, None)) + + // assert that the peer called `networkDb.getNode` - because it received a Peer.Connect(remoteNodeId, None) + awaitAssert(mockNetworkDb.getNode(remoteNodeId).wasCalled(once)) + } +} From 20ea9d0e1dd925cd2f0ad6f2d5ac810b23971e4e Mon Sep 17 00:00:00 2001 From: araspitzu Date: Wed, 3 Jul 2019 15:52:03 +0200 Subject: [PATCH 04/12] Reject payments for expired invoices (#1057) * Reject payments for expired invoices --- .../scala/fr/acinq/eclair/db/PaymentsDb.scala | 1 + .../eclair/payment/LocalPaymentHandler.scala | 2 ++ .../acinq/eclair/payment/PaymentRequest.scala | 10 ++++++++- .../eclair/payment/PaymentHandlerSpec.scala | 21 +++++++++++++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/db/PaymentsDb.scala b/eclair-core/src/main/scala/fr/acinq/eclair/db/PaymentsDb.scala index 38b1f60e8d..b13e190446 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/db/PaymentsDb.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/db/PaymentsDb.scala @@ -39,6 +39,7 @@ trait PaymentsDb { def getPaymentRequest(paymentHash: ByteVector32): Option[PaymentRequest] + // returns non paid payment request def getPendingPaymentRequestAndPreimage(paymentHash: ByteVector32): Option[(ByteVector32, PaymentRequest)] def listPaymentRequests(from: Long, to: Long): Seq[PaymentRequest] diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/payment/LocalPaymentHandler.scala b/eclair-core/src/main/scala/fr/acinq/eclair/payment/LocalPaymentHandler.scala index d5daaa8d1f..1070f3ef37 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/payment/LocalPaymentHandler.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/payment/LocalPaymentHandler.scala @@ -65,6 +65,8 @@ class LocalPaymentHandler(nodeParams: NodeParams) extends Actor with ActorLoggin // it must not be greater than two times the requested amount. // see https://github.com/lightningnetwork/lightning-rfc/blob/master/04-onion-routing.md#failure-messages paymentRequest.amount match { + case _ if paymentRequest.isExpired => + sender ! CMD_FAIL_HTLC(htlc.id, Right(IncorrectOrUnknownPaymentDetails(htlc.amountMsat)), commit = true) case _ if htlc.cltvExpiry < minFinalExpiry => sender ! CMD_FAIL_HTLC(htlc.id, Right(FinalExpiryTooSoon), commit = true) case Some(amount) if MilliSatoshi(htlc.amountMsat) < amount => diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/payment/PaymentRequest.scala b/eclair-core/src/main/scala/fr/acinq/eclair/payment/PaymentRequest.scala index b35b0d7b19..b5c6da04f9 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/payment/PaymentRequest.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/payment/PaymentRequest.scala @@ -23,7 +23,8 @@ import fr.acinq.eclair.payment.PaymentRequest._ import scodec.Codec import scodec.bits.{BitVector, ByteOrdering, ByteVector} import scodec.codecs.{list, ubyte} - +import scala.concurrent.duration._ +import scala.compat.Platform import scala.util.Try /** @@ -76,6 +77,11 @@ case class PaymentRequest(prefix: String, amount: Option[MilliSatoshi], timestam case cltvExpiry: PaymentRequest.MinFinalCltvExpiry => cltvExpiry.toLong } + def isExpired: Boolean = expiry match { + case Some(expiryTime) => timestamp + expiryTime <= Platform.currentTime.milliseconds.toSeconds + case None => timestamp + DEFAULT_EXPIRY_SECONDS <= Platform.currentTime.milliseconds.toSeconds + } + /** * * @return the hash of this payment request @@ -104,6 +110,8 @@ case class PaymentRequest(prefix: String, amount: Option[MilliSatoshi], timestam object PaymentRequest { + val DEFAULT_EXPIRY_SECONDS = 3600 + val prefixes = Map( Block.RegtestGenesisBlock.hash -> "lnbcrt", Block.TestnetGenesisBlock.hash -> "lntb", diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/payment/PaymentHandlerSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/payment/PaymentHandlerSpec.scala index 90f7c8cbfd..9edf987b85 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/payment/PaymentHandlerSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/payment/PaymentHandlerSpec.scala @@ -52,6 +52,7 @@ class PaymentHandlerSpec extends TestKit(ActorSystem("test")) with FunSuiteLike val pr = sender.expectMsgType[PaymentRequest] assert(nodeParams.db.payments.getIncomingPayment(pr.paymentHash).isEmpty) assert(nodeParams.db.payments.getPendingPaymentRequestAndPreimage(pr.paymentHash).isDefined) + assert(!nodeParams.db.payments.getPendingPaymentRequestAndPreimage(pr.paymentHash).get._2.isExpired) val add = UpdateAddHtlc(ByteVector32(ByteVector.fill(32)(1)), 0, amountMsat.amount, pr.paymentHash, expiry, ByteVector.empty) sender.send(handler, add) @@ -149,4 +150,24 @@ class PaymentHandlerSpec extends TestKit(ActorSystem("test")) with FunSuiteLike sender.send(handler, ReceivePayment(Some(MilliSatoshi(42000)), "1 coffee without routing info")) assert(sender.expectMsgType[PaymentRequest].routingInfo === Nil) } + + test("LocalPaymentHandler should reject incoming payments if the payment request is expired") { + val nodeParams = Alice.nodeParams + val handler = TestActorRef[LocalPaymentHandler](LocalPaymentHandler.props(nodeParams)) + val sender = TestProbe() + val eventListener = TestProbe() + system.eventStream.subscribe(eventListener.ref, classOf[PaymentReceived]) + + val amountMsat = MilliSatoshi(42000) + val expiry = Globals.blockCount.get() + 12 + + sender.send(handler, ReceivePayment(Some(amountMsat), "some desc", expirySeconds_opt = Some(0))) + val pr = sender.expectMsgType[PaymentRequest] + + val add = UpdateAddHtlc(ByteVector32(ByteVector.fill(32)(1)), 0, amountMsat.amount, pr.paymentHash, expiry, ByteVector.empty) + sender.send(handler, add) + + sender.expectMsgType[CMD_FAIL_HTLC] + assert(nodeParams.db.payments.getIncomingPayment(pr.paymentHash).isEmpty) + } } From 6906ecb403a29ffaba8417e96bd3369d6b045d36 Mon Sep 17 00:00:00 2001 From: Fabrice Drouin Date: Wed, 3 Jul 2019 17:23:12 +0200 Subject: [PATCH 05/12] Set version to v0.3.1 (#1061) --- eclair-core/pom.xml | 2 +- eclair-node-gui/pom.xml | 2 +- eclair-node/pom.xml | 2 +- pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/eclair-core/pom.xml b/eclair-core/pom.xml index 22a2320ef2..8899894e5c 100644 --- a/eclair-core/pom.xml +++ b/eclair-core/pom.xml @@ -21,7 +21,7 @@ fr.acinq.eclair eclair_2.11 - 0.3.1-SNAPSHOT + 0.3.1 eclair-core_2.11 diff --git a/eclair-node-gui/pom.xml b/eclair-node-gui/pom.xml index a4d6c767fb..b7af9623b9 100644 --- a/eclair-node-gui/pom.xml +++ b/eclair-node-gui/pom.xml @@ -21,7 +21,7 @@ fr.acinq.eclair eclair_2.11 - 0.3.1-SNAPSHOT + 0.3.1 eclair-node-gui_2.11 diff --git a/eclair-node/pom.xml b/eclair-node/pom.xml index b51624433c..071d1912eb 100644 --- a/eclair-node/pom.xml +++ b/eclair-node/pom.xml @@ -21,7 +21,7 @@ fr.acinq.eclair eclair_2.11 - 0.3.1-SNAPSHOT + 0.3.1 eclair-node_2.11 diff --git a/pom.xml b/pom.xml index eadb3b89d5..9079595c61 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ fr.acinq.eclair eclair_2.11 - 0.3.1-SNAPSHOT + 0.3.1 pom From bbe07c2c422e24e7c9bbde2315d1ae6592fcfe8b Mon Sep 17 00:00:00 2001 From: Fabrice Drouin Date: Thu, 4 Jul 2019 10:00:44 +0200 Subject: [PATCH 06/12] Set version to 0.3.2-SNAPSHOT (#1062) --- eclair-core/pom.xml | 2 +- eclair-node-gui/pom.xml | 2 +- eclair-node/pom.xml | 2 +- pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/eclair-core/pom.xml b/eclair-core/pom.xml index 8899894e5c..9df8a928e3 100644 --- a/eclair-core/pom.xml +++ b/eclair-core/pom.xml @@ -21,7 +21,7 @@ fr.acinq.eclair eclair_2.11 - 0.3.1 + 0.3.2-SNAPSHOT eclair-core_2.11 diff --git a/eclair-node-gui/pom.xml b/eclair-node-gui/pom.xml index b7af9623b9..fb30711d1b 100644 --- a/eclair-node-gui/pom.xml +++ b/eclair-node-gui/pom.xml @@ -21,7 +21,7 @@ fr.acinq.eclair eclair_2.11 - 0.3.1 + 0.3.2-SNAPSHOT eclair-node-gui_2.11 diff --git a/eclair-node/pom.xml b/eclair-node/pom.xml index 071d1912eb..de06319706 100644 --- a/eclair-node/pom.xml +++ b/eclair-node/pom.xml @@ -21,7 +21,7 @@ fr.acinq.eclair eclair_2.11 - 0.3.1 + 0.3.2-SNAPSHOT eclair-node_2.11 diff --git a/pom.xml b/pom.xml index 9079595c61..ed1e45b218 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ fr.acinq.eclair eclair_2.11 - 0.3.1 + 0.3.2-SNAPSHOT pom From 683294ee578a049b8c579ab6b81567fca0a08fe8 Mon Sep 17 00:00:00 2001 From: Pierre-Marie Padiou Date: Thu, 4 Jul 2019 14:06:05 +0200 Subject: [PATCH 07/12] Use a `RelayResult` class instead of an `Either` (#1064) It is functionnaly the same but it's cleaner and removes the need for tuples in the success case. --- .../fr/acinq/eclair/payment/Relayer.scala | 39 ++++++++++++------- .../eclair/payment/ChannelSelectionSpec.scala | 16 ++++---- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/payment/Relayer.scala b/eclair-core/src/main/scala/fr/acinq/eclair/payment/Relayer.scala index dd27dc096b..1a75ee2083 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/payment/Relayer.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/payment/Relayer.scala @@ -111,11 +111,11 @@ class Relayer(nodeParams: NodeParams, register: ActorRef, paymentHandler: ActorR paymentHandler forward addHtlc } case Success(r: RelayPayload) => - handleRelay(r, channelUpdates, node2channels, previousFailures) match { - case Left(cmdFail) => + handleRelay(r, channelUpdates, node2channels, previousFailures, nodeParams.chainHash) match { + case RelayFailure(cmdFail) => log.info(s"rejecting htlc #${add.id} paymentHash=${add.paymentHash} from channelId=${add.channelId} to shortChannelId=${r.payload.shortChannelId} reason=${cmdFail.reason}") commandBuffer ! CommandBuffer.CommandSend(add.channelId, add.id, cmdFail) - case Right((selectedShortChannelId, cmdAdd)) => + case RelaySuccess(selectedShortChannelId, cmdAdd) => log.info(s"forwarding htlc #${add.id} paymentHash=${add.paymentHash} from channelId=${add.channelId} to shortChannelId=$selectedShortChannelId") register ! Register.ForwardShortId(selectedShortChannelId, cmdAdd) } @@ -264,6 +264,12 @@ object Relayer { } } + // @formatter:off + sealed trait RelayResult + case class RelayFailure(cmdFail: CMD_FAIL_HTLC) extends RelayResult + case class RelaySuccess(shortChannelId: ShortChannelId, cmdAdd: CMD_ADD_HTLC) extends RelayResult + // @formatter:on + /** * Handle an incoming htlc when we are a relaying node * @@ -272,7 +278,7 @@ object Relayer { * - a CMD_FAIL_HTLC to be sent back upstream * - a CMD_ADD_HTLC to propagate downstream */ - def handleRelay(relayPayload: RelayPayload, channelUpdates: Map[ShortChannelId, OutgoingChannel], node2channels: mutable.Map[PublicKey, mutable.Set[ShortChannelId]] with mutable.MultiMap[PublicKey, ShortChannelId], previousFailures: Seq[AddHtlcFailed])(implicit log: LoggingAdapter): Either[CMD_FAIL_HTLC, (ShortChannelId, CMD_ADD_HTLC)] = { + def handleRelay(relayPayload: RelayPayload, channelUpdates: Map[ShortChannelId, OutgoingChannel], node2channels: mutable.Map[PublicKey, mutable.Set[ShortChannelId]] with mutable.MultiMap[PublicKey, ShortChannelId], previousFailures: Seq[AddHtlcFailed], chainHash: ByteVector32)(implicit log: LoggingAdapter): RelayResult = { import relayPayload._ log.info(s"relaying htlc #${add.id} paymentHash={} from channelId={} to requestedShortChannelId={} previousAttempts={}", add.paymentHash, add.channelId, relayPayload.payload.shortChannelId, previousFailures.size) val alreadyTried = previousFailures.flatMap(_.channelUpdate).map(_.shortChannelId) @@ -285,7 +291,7 @@ object Relayer { .find(_.channelUpdate.map(_.shortChannelId).contains(relayPayload.payload.shortChannelId)) // otherwise we return the error for the first channel tried .getOrElse(previousFailures.head) - Left(CMD_FAIL_HTLC(add.id, Right(translateError(error)), commit = true)) + RelayFailure(CMD_FAIL_HTLC(add.id, Right(translateError(error)), commit = true)) case channelUpdate_opt => relayOrFail(relayPayload, channelUpdate_opt, previousFailures) } @@ -302,8 +308,13 @@ object Relayer { val requestedShortChannelId = relayPayload.payload.shortChannelId log.debug(s"selecting next channel for htlc #${add.id} paymentHash={} from channelId={} to requestedShortChannelId={} previousAttempts={}", add.paymentHash, add.channelId, requestedShortChannelId, alreadyTried.size) // first we find out what is the next node - channelUpdates.get(requestedShortChannelId) match { + val nextNodeId_opt = channelUpdates.get(requestedShortChannelId) match { case Some(OutgoingChannel(nextNodeId, _, _)) => + Some(nextNodeId) + case None => None + } + nextNodeId_opt match { + case Some(nextNodeId) => log.debug(s"next hop for htlc #{} paymentHash={} is nodeId={}", add.id, add.paymentHash, nextNodeId) // then we retrieve all known channels to this node val allChannels = node2channels.getOrElse(nextNodeId, Set.empty[ShortChannelId]) @@ -318,7 +329,7 @@ object Relayer { log.debug(s"candidate channel for htlc #${add.id} paymentHash=${add.paymentHash}: shortChannelId={} balanceMsat={} channelUpdate={} relayResult={}", shortChannelId, channelInfo_opt.map(_.commitments.availableBalanceForSendMsat).getOrElse(""), channelUpdate_opt.getOrElse(""), relayResult) (shortChannelId, channelInfo_opt, relayResult) } - .collect { case (shortChannelId, Some(channelInfo), Right(_)) => (shortChannelId, channelInfo.commitments.availableBalanceForSendMsat) } + .collect { case (shortChannelId, Some(channelInfo), _: RelaySuccess) => (shortChannelId, channelInfo.commitments.availableBalanceForSendMsat) } .filter(_._2 > relayPayload.payload.amtToForward) // we only keep channels that have enough balance to handle this payment .toList // needed for ordering .sortBy(_._2) // we want to use the channel with the lowest available balance that can process the payment @@ -345,21 +356,21 @@ object Relayer { * channel, because some parameters don't match with our settings for that channel. In that case we directly fail the * htlc. */ - def relayOrFail(relayPayload: RelayPayload, channelUpdate_opt: Option[ChannelUpdate], previousFailures: Seq[AddHtlcFailed] = Seq.empty)(implicit log: LoggingAdapter): Either[CMD_FAIL_HTLC, (ShortChannelId, CMD_ADD_HTLC)] = { + def relayOrFail(relayPayload: RelayPayload, channelUpdate_opt: Option[ChannelUpdate], previousFailures: Seq[AddHtlcFailed] = Seq.empty)(implicit log: LoggingAdapter): RelayResult = { import relayPayload._ channelUpdate_opt match { case None => - Left(CMD_FAIL_HTLC(add.id, Right(UnknownNextPeer), commit = true)) + RelayFailure(CMD_FAIL_HTLC(add.id, Right(UnknownNextPeer), commit = true)) case Some(channelUpdate) if !Announcements.isEnabled(channelUpdate.channelFlags) => - Left(CMD_FAIL_HTLC(add.id, Right(ChannelDisabled(channelUpdate.messageFlags, channelUpdate.channelFlags, channelUpdate)), commit = true)) + RelayFailure(CMD_FAIL_HTLC(add.id, Right(ChannelDisabled(channelUpdate.messageFlags, channelUpdate.channelFlags, channelUpdate)), commit = true)) case Some(channelUpdate) if payload.amtToForward < channelUpdate.htlcMinimumMsat => - Left(CMD_FAIL_HTLC(add.id, Right(AmountBelowMinimum(payload.amtToForward, channelUpdate)), commit = true)) + RelayFailure(CMD_FAIL_HTLC(add.id, Right(AmountBelowMinimum(payload.amtToForward, channelUpdate)), commit = true)) case Some(channelUpdate) if relayPayload.expiryDelta != channelUpdate.cltvExpiryDelta => - Left(CMD_FAIL_HTLC(add.id, Right(IncorrectCltvExpiry(payload.outgoingCltvValue, channelUpdate)), commit = true)) + RelayFailure(CMD_FAIL_HTLC(add.id, Right(IncorrectCltvExpiry(payload.outgoingCltvValue, channelUpdate)), commit = true)) case Some(channelUpdate) if relayPayload.relayFeeMsat < nodeFee(channelUpdate.feeBaseMsat, channelUpdate.feeProportionalMillionths, payload.amtToForward) => - Left(CMD_FAIL_HTLC(add.id, Right(FeeInsufficient(add.amountMsat, channelUpdate)), commit = true)) + RelayFailure(CMD_FAIL_HTLC(add.id, Right(FeeInsufficient(add.amountMsat, channelUpdate)), commit = true)) case Some(channelUpdate) => - Right((channelUpdate.shortChannelId, CMD_ADD_HTLC(payload.amtToForward, add.paymentHash, payload.outgoingCltvValue, nextPacket.serialize, upstream = Right(add), commit = true, previousFailures = previousFailures))) + RelaySuccess(channelUpdate.shortChannelId, CMD_ADD_HTLC(payload.amtToForward, add.paymentHash, payload.outgoingCltvValue, nextPacket.serialize, upstream = Right(add), commit = true, previousFailures = previousFailures)) } } diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/payment/ChannelSelectionSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/payment/ChannelSelectionSpec.scala index 41f83245b4..8eab3c0e7f 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/payment/ChannelSelectionSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/payment/ChannelSelectionSpec.scala @@ -20,7 +20,7 @@ import fr.acinq.bitcoin.{Block, ByteVector32} import fr.acinq.bitcoin.Crypto.PublicKey import fr.acinq.eclair.channel.{CMD_ADD_HTLC, CMD_FAIL_HTLC} import fr.acinq.eclair.crypto.Sphinx -import fr.acinq.eclair.payment.Relayer.{OutgoingChannel, RelayPayload} +import fr.acinq.eclair.payment.Relayer.{OutgoingChannel, RelayFailure, RelayPayload, RelaySuccess} import fr.acinq.eclair.router.Announcements import fr.acinq.eclair.wire._ import fr.acinq.eclair.{ShortChannelId, randomBytes32, randomKey} @@ -50,24 +50,24 @@ class ChannelSelectionSpec extends FunSuite { implicit val log = akka.event.NoLogging // nominal case - assert(Relayer.relayOrFail(relayPayload, Some(channelUpdate)) === Right((ShortChannelId(12345), CMD_ADD_HTLC(relayPayload.payload.amtToForward, relayPayload.add.paymentHash, relayPayload.payload.outgoingCltvValue, relayPayload.nextPacket.serialize, upstream = Right(relayPayload.add), commit = true)))) + assert(Relayer.relayOrFail(relayPayload, Some(channelUpdate)) === RelaySuccess(ShortChannelId(12345), CMD_ADD_HTLC(relayPayload.payload.amtToForward, relayPayload.add.paymentHash, relayPayload.payload.outgoingCltvValue, relayPayload.nextPacket.serialize, upstream = Right(relayPayload.add), commit = true))) // no channel_update - assert(Relayer.relayOrFail(relayPayload, channelUpdate_opt = None) === Left(CMD_FAIL_HTLC(relayPayload.add.id, Right(UnknownNextPeer), commit = true))) + assert(Relayer.relayOrFail(relayPayload, channelUpdate_opt = None) === RelayFailure(CMD_FAIL_HTLC(relayPayload.add.id, Right(UnknownNextPeer), commit = true))) // channel disabled val channelUpdate_disabled = channelUpdate.copy(channelFlags = Announcements.makeChannelFlags(true, enable = false)) - assert(Relayer.relayOrFail(relayPayload, Some(channelUpdate_disabled)) === Left(CMD_FAIL_HTLC(relayPayload.add.id, Right(ChannelDisabled(channelUpdate_disabled.messageFlags, channelUpdate_disabled.channelFlags, channelUpdate_disabled)), commit = true))) + assert(Relayer.relayOrFail(relayPayload, Some(channelUpdate_disabled)) === RelayFailure(CMD_FAIL_HTLC(relayPayload.add.id, Right(ChannelDisabled(channelUpdate_disabled.messageFlags, channelUpdate_disabled.channelFlags, channelUpdate_disabled)), commit = true))) // amount too low val relayPayload_toolow = relayPayload.copy(payload = relayPayload.payload.copy(amtToForward = 99)) - assert(Relayer.relayOrFail(relayPayload_toolow, Some(channelUpdate)) === Left(CMD_FAIL_HTLC(relayPayload.add.id, Right(AmountBelowMinimum(relayPayload_toolow.payload.amtToForward, channelUpdate)), commit = true))) + assert(Relayer.relayOrFail(relayPayload_toolow, Some(channelUpdate)) === RelayFailure(CMD_FAIL_HTLC(relayPayload.add.id, Right(AmountBelowMinimum(relayPayload_toolow.payload.amtToForward, channelUpdate)), commit = true))) // incorrect cltv expiry val relayPayload_incorrectcltv = relayPayload.copy(payload = relayPayload.payload.copy(outgoingCltvValue = 42)) - assert(Relayer.relayOrFail(relayPayload_incorrectcltv, Some(channelUpdate)) === Left(CMD_FAIL_HTLC(relayPayload.add.id, Right(IncorrectCltvExpiry(relayPayload_incorrectcltv.payload.outgoingCltvValue, channelUpdate)), commit = true))) + assert(Relayer.relayOrFail(relayPayload_incorrectcltv, Some(channelUpdate)) === RelayFailure(CMD_FAIL_HTLC(relayPayload.add.id, Right(IncorrectCltvExpiry(relayPayload_incorrectcltv.payload.outgoingCltvValue, channelUpdate)), commit = true))) // insufficient fee val relayPayload_insufficientfee = relayPayload.copy(payload = relayPayload.payload.copy(amtToForward = 998910)) - assert(Relayer.relayOrFail(relayPayload_insufficientfee, Some(channelUpdate)) === Left(CMD_FAIL_HTLC(relayPayload.add.id, Right(FeeInsufficient(relayPayload_insufficientfee.add.amountMsat, channelUpdate)), commit = true))) + assert(Relayer.relayOrFail(relayPayload_insufficientfee, Some(channelUpdate)) === RelayFailure(CMD_FAIL_HTLC(relayPayload.add.id, Right(FeeInsufficient(relayPayload_insufficientfee.add.amountMsat, channelUpdate)), commit = true))) // note that a generous fee is ok! val relayPayload_highfee = relayPayload.copy(payload = relayPayload.payload.copy(amtToForward = 900000)) - assert(Relayer.relayOrFail(relayPayload_highfee, Some(channelUpdate)) === Right((ShortChannelId(12345), CMD_ADD_HTLC(relayPayload_highfee.payload.amtToForward, relayPayload_highfee.add.paymentHash, relayPayload_highfee.payload.outgoingCltvValue, relayPayload_highfee.nextPacket.serialize, upstream = Right(relayPayload.add), commit = true)))) + assert(Relayer.relayOrFail(relayPayload_highfee, Some(channelUpdate)) === RelaySuccess(ShortChannelId(12345), CMD_ADD_HTLC(relayPayload_highfee.payload.amtToForward, relayPayload_highfee.add.paymentHash, relayPayload_highfee.payload.outgoingCltvValue, relayPayload_highfee.nextPacket.serialize, upstream = Right(relayPayload.add), commit = true))) } test("channel selection") { From 9afb26e09c69dd5d6a14732baf5dcdf2b7a9142b Mon Sep 17 00:00:00 2001 From: araspitzu Date: Fri, 5 Jul 2019 09:10:06 +0200 Subject: [PATCH 08/12] Add eclair-cli to eclair's docker image (#1063) * Add eclair-cli to eclair's docker image * Add instructions to use eclair-cli inside the docker container --- Dockerfile | 8 ++++++++ README.md | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/Dockerfile b/Dockerfile index 4f8f2a2f29..475a939822 100644 --- a/Dockerfile +++ b/Dockerfile @@ -44,6 +44,14 @@ RUN mvn package -pl eclair-node -am -DskipTests -Dgit.commit.id=notag -Dgit.comm # We currently use a debian image for runtime because of some jni-related issue with sqlite FROM openjdk:8u181-jre-slim WORKDIR /app + +# install jq for eclair-cli +RUN apt-get update && apt-get install -y bash jq curl + +# copy and install eclair-cli executable +COPY --from=BUILD /usr/src/eclair-core/eclair-cli . +RUN chmod +x eclair-cli && mv eclair-cli /sbin/eclair-cli + # Eclair only needs the eclair-node-*.jar to run COPY --from=BUILD /usr/src/eclair-node/target/eclair-node-*.jar . RUN ln `ls` eclair-node.jar diff --git a/README.md b/README.md index e5c086d723..cf308835b6 100644 --- a/README.md +++ b/README.md @@ -163,6 +163,11 @@ If you want to persist the data directory, you can make the volume to your host docker run -ti --rm -v "/path_on_host:/data" -e "JAVA_OPTS=-Declair.printToConsole" acinq/eclair ``` +If you enabled the API you can check the status of eclair using the command line tool: +``` +docker exec eclair-cli -p foobar getinfo +``` + ## Plugins For advanced usage, Eclair supports plugins written in Scala, Java, or any JVM-compatible language. From 22548733e6d2732289fd067e6341ef540be10734 Mon Sep 17 00:00:00 2001 From: Bastien Teinturier <31281497+t-bast@users.noreply.github.com> Date: Mon, 8 Jul 2019 10:05:18 +0200 Subject: [PATCH 09/12] Add a few improvements to tlv. (#1065) Hide some internals (tlvFallback, generictlv codecs). Add a length-prefixed tlv stream codec. --- .../fr/acinq/eclair/wire/TlvCodecs.scala | 12 +++-- .../fr/acinq/eclair/wire/TlvCodecsSpec.scala | 54 ++++++++++++++----- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/TlvCodecs.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/TlvCodecs.scala index 986f7c1d3a..978afa78dd 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/TlvCodecs.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/TlvCodecs.scala @@ -28,9 +28,9 @@ import scala.util.Try object TlvCodecs { - val genericTlv: Codec[GenericTlv] = (("type" | varint) :: variableSizeBytesLong(varintoverflow, bytes)).as[GenericTlv] + private val genericTlv: Codec[GenericTlv] = (("type" | varint) :: variableSizeBytesLong(varintoverflow, bytes)).as[GenericTlv] - def tlvFallback(codec: Codec[Tlv]): Codec[Tlv] = discriminatorFallback(genericTlv, codec).xmap({ + private def tlvFallback(codec: Codec[Tlv]): Codec[Tlv] = discriminatorFallback(genericTlv, codec).xmap({ case Left(l) => l case Right(r) => r }, { @@ -44,9 +44,15 @@ object TlvCodecs { * * @param codec codec used for the tlv records contained in the stream. */ - def tlvStream(codec: Codec[Tlv]): Codec[TlvStream] = list(codec).exmap( + def tlvStream(codec: Codec[Tlv]): Codec[TlvStream] = list(tlvFallback(codec)).exmap( records => Attempt.fromTry(Try(TlvStream(records))), stream => Attempt.successful(stream.records.toList) ) + /** + * When used inside a message, a tlv stream needs to specify its length. + * Note that some messages will have an independent length field and won't need this codec. + */ + def lengthPrefixedTlvStream(codec: Codec[Tlv]): Codec[TlvStream] = variableSizeBytesLong(CommonCodecs.varintoverflow, tlvStream(codec)) + } diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/wire/TlvCodecsSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/wire/TlvCodecsSpec.scala index a4c4541b8e..838cc891fe 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/wire/TlvCodecsSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/wire/TlvCodecsSpec.scala @@ -38,14 +38,13 @@ class TlvCodecsSpec extends FunSuite { val testCases = Seq( (hex"01 08 000000000000002a", TestType1(42)), (hex"02 08 0000000000000226", TestType2(ShortChannelId(550))), - (hex"03 31 02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619 0000000000000231 0000000000000451", TestType3(PublicKey(hex"02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619"), 561, 1105)), - (hex"ff1234567890123456 fd0001 10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010010101010101", GenericTlv(6211610197754262546L, hex"10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010010101010101")) + (hex"03 31 02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619 0000000000000231 0000000000000451", TestType3(PublicKey(hex"02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619"), 561, 1105)) ) for ((bin, expected) <- testCases) { - val decoded = testTlvCodec.decode(bin.toBitVector).require.value.asInstanceOf[Tlv] + val decoded = testTlvCodec.decode(bin.bits).require.value.asInstanceOf[Tlv] assert(decoded === expected) - val encoded = testTlvCodec.encode(expected).require.toByteVector + val encoded = testTlvCodec.encode(expected).require.bytes assert(encoded === bin) } } @@ -65,7 +64,7 @@ class TlvCodecsSpec extends FunSuite { ) for (testCase <- testCases) { - assert(testTlvCodec.decode(testCase.toBitVector).isFailure) + assert(testTlvCodec.decode(testCase.bits).isFailure) } } @@ -79,7 +78,7 @@ class TlvCodecsSpec extends FunSuite { ) for (testCase <- testCases) { - assert(tlvStream(testTlvCodec).decode(testCase.toBitVector).isFailure, testCase) + assert(tlvStream(testTlvCodec).decode(testCase.bits).isFailure, testCase) } } @@ -90,6 +89,11 @@ class TlvCodecsSpec extends FunSuite { assertThrows[IllegalArgumentException](TlvStream(Seq(TestType2(ShortChannelId(1105)), TestType1(561)))) // invalid ordering } + test("encoded/decode empty tlv stream") { + assert(tlvStream(testTlvCodec).decode(hex"".bits).require.value === TlvStream(Nil)) + assert(tlvStream(testTlvCodec).encode(TlvStream(Nil)).require.bytes === hex"") + } + test("encode/decode tlv stream") { val bin = hex"01080000000000000231 02080000000000000451 033102eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f28368661900000000000002310000000000000451" val expected = Seq( @@ -98,10 +102,10 @@ class TlvCodecsSpec extends FunSuite { TestType3(PublicKey(hex"02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619"), 561, 1105) ) - val decoded = tlvStream(testTlvCodec).decode(bin.toBitVector).require.value + val decoded = tlvStream(testTlvCodec).decode(bin.bits).require.value assert(decoded === TlvStream(expected)) - val encoded = tlvStream(testTlvCodec).encode(TlvStream(expected)).require.toByteVector + val encoded = tlvStream(testTlvCodec).encode(TlvStream(expected)).require.bytes assert(encoded === bin) } @@ -113,13 +117,37 @@ class TlvCodecsSpec extends FunSuite { TestType13(42) ) - val decoded = tlvStream(testTlvCodec).decode(bin.toBitVector).require.value + val decoded = tlvStream(testTlvCodec).decode(bin.bits).require.value assert(decoded === TlvStream(expected)) - val encoded = tlvStream(testTlvCodec).encode(TlvStream(expected)).require.toByteVector + val encoded = tlvStream(testTlvCodec).encode(TlvStream(expected)).require.bytes assert(encoded === bin) } + test("encode/decode length-prefixed tlv stream") { + val codec = lengthPrefixedTlvStream(testTlvCodec) + val testCases = Seq( + hex"47 01080000000000000231 02080000000000000451 033102eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f28368661900000000000002310000000000000451", + hex"fd5301 01080000000000000231 02080000000000000451 033102eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f28368661900000000000002310000000000000451 ff6543210987654321 fd0001 10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010010101010101" + ) + + for (testCase <- testCases) { + assert(codec.encode(codec.decode(testCase.bits).require.value).require.bytes === testCase) + } + } + + test("decode invalid length-prefixed tlv stream") { + val testCases = Seq( + hex"48 01080000000000000231 02080000000000000451 033102eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f28368661900000000000002310000000000000451", + hex"46 01080000000000000231 02080000000000000451 033102eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f28368661900000000000002310000000000000451", + hex"01080000000000000231 02080000000000000451 033102eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f28368661900000000000002310000000000000451" + ) + + for (testCase <- testCases) { + assert(lengthPrefixedTlvStream(testTlvCodec).decode(testCase.bits).isFailure) + } + } + } object TlvCodecsSpec { @@ -135,12 +163,11 @@ object TlvCodecsSpec { val testCodec2: Codec[TestType2] = (("length" | constant(hex"08")) :: ("short_channel_id" | shortchannelid)).as[TestType2] val testCodec3: Codec[TestType3] = (("length" | constant(hex"31")) :: ("node_id" | publicKey) :: ("value_1" | uint64) :: ("value_2" | uint64)).as[TestType3] val testCodec13: Codec[TestType13] = (("length" | constant(hex"02")) :: ("value" | uint16)).as[TestType13] - val testTlvCodec = tlvFallback(discriminated[Tlv].by(varint) + val testTlvCodec = discriminated[Tlv].by(varint) .typecase(1, testCodec1) .typecase(2, testCodec2) .typecase(3, testCodec3) .typecase(13, testCodec13) - ) sealed trait OtherTlv extends Tlv case class OtherType1(uintValue: UInt64) extends OtherTlv { override val `type` = UInt64(10) } @@ -148,10 +175,9 @@ object TlvCodecsSpec { val otherCodec1: Codec[OtherType1] = (("length" | constant(hex"08")) :: ("value" | uint64)).as[OtherType1] val otherCodec2: Codec[OtherType2] = (("length" | constant(hex"04")) :: ("value" | uint32)).as[OtherType2] - val otherTlvCodec = tlvFallback(discriminated[Tlv].by(varint) + val otherTlvCodec = discriminated[Tlv].by(varint) .typecase(10, otherCodec1) .typecase(11, otherCodec2) - ) // @formatter:on } From e5c5a4cfbc4906f1da73f0c21988a8a9d360fb0a Mon Sep 17 00:00:00 2001 From: Pierre-Marie Padiou Date: Mon, 8 Jul 2019 17:14:01 +0200 Subject: [PATCH 10/12] Handle unknown fields in network announcements (#1047) All the data contained in `node_announcement`, `channel_announcement` and `channel_update` is to be included in the signature, including unknown trailing fields. We were ignoring them, causing signature verification to fail when there was unknown fields. In the case of `channel_update` there is a backward compatibility issue to handle, because when persisting channel data in state `NORMAL`, we used to store the `channel_update` followed by other data, and without prefixing it with size information. To work around that we use the same trick as before, based on an additional discriminator codec. --- .../acinq/eclair/crypto/LocalKeyManager.scala | 12 +- .../acinq/eclair/router/Announcements.scala | 26 +-- .../fr/acinq/eclair/wire/ChannelCodecs.scala | 36 +++- .../eclair/wire/LightningMessageCodecs.scala | 43 ++-- .../eclair/wire/LightningMessageTypes.scala | 9 +- .../acinq/eclair/db/BackupHandlerSpec.scala | 3 +- .../fr/acinq/eclair/db/ChannelStateSpec.scala | 147 -------------- .../acinq/eclair/db/SqliteAuditDbSpec.scala | 5 +- .../eclair/db/SqliteChannelsDbSpec.scala | 5 +- .../fr/acinq/eclair/io/HtlcReaperSpec.scala | 5 +- .../scala/fr/acinq/eclair/io/PeerSpec.scala | 26 ++- .../fr/acinq/eclair/io/SwitchboardSpec.scala | 8 +- .../acinq/eclair/wire/ChannelCodecsSpec.scala | 189 +++++++++++++++++- 13 files changed, 292 insertions(+), 222 deletions(-) delete mode 100644 eclair-core/src/test/scala/fr/acinq/eclair/db/ChannelStateSpec.scala diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/crypto/LocalKeyManager.scala b/eclair-core/src/main/scala/fr/acinq/eclair/crypto/LocalKeyManager.scala index 3308698347..2bf80bccc4 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/crypto/LocalKeyManager.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/crypto/LocalKeyManager.scala @@ -121,6 +121,7 @@ class LocalKeyManager(seed: ByteVector, chainHash: ByteVector32) extends KeyMana Transactions.sign(tx, currentKey) } + /** * Ths method is used to spend revoked transactions, with the corresponding revocation key * @@ -137,13 +138,8 @@ class LocalKeyManager(seed: ByteVector, chainHash: ByteVector32) extends KeyMana } override def signChannelAnnouncement(channelKeyPath: DeterministicWallet.KeyPath, chainHash: ByteVector32, shortChannelId: ShortChannelId, remoteNodeId: PublicKey, remoteFundingKey: PublicKey, features: ByteVector): (ByteVector64, ByteVector64) = { - val witness = if (Announcements.isNode1(nodeId, remoteNodeId)) { - Announcements.channelAnnouncementWitnessEncode(chainHash, shortChannelId, nodeId, remoteNodeId, fundingPublicKey(channelKeyPath).publicKey, remoteFundingKey, features) - } else { - Announcements.channelAnnouncementWitnessEncode(chainHash, shortChannelId, remoteNodeId, nodeId, remoteFundingKey, fundingPublicKey(channelKeyPath).publicKey, features) - } - val nodeSig = Crypto.sign(witness, nodeKey.privateKey) - val bitcoinSig = Crypto.sign(witness, fundingPrivateKey(channelKeyPath).privateKey) - (nodeSig, bitcoinSig) + val localNodeSecret = nodeKey.privateKey + val localFundingPrivKey = fundingPrivateKey(channelKeyPath).privateKey + Announcements.signChannelAnnouncement(chainHash, shortChannelId, localNodeSecret, remoteNodeId, localFundingPrivKey, remoteFundingKey, features) } } diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/router/Announcements.scala b/eclair-core/src/main/scala/fr/acinq/eclair/router/Announcements.scala index 4a46116644..2ade1fe802 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/router/Announcements.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/router/Announcements.scala @@ -32,20 +32,20 @@ import scala.concurrent.duration._ */ object Announcements { - def channelAnnouncementWitnessEncode(chainHash: ByteVector32, shortChannelId: ShortChannelId, nodeId1: PublicKey, nodeId2: PublicKey, bitcoinKey1: PublicKey, bitcoinKey2: PublicKey, features: ByteVector): ByteVector = - sha256(sha256(serializationResult(LightningMessageCodecs.channelAnnouncementWitnessCodec.encode(features :: chainHash :: shortChannelId :: nodeId1 :: nodeId2 :: bitcoinKey1 :: bitcoinKey2 :: HNil)))) + def channelAnnouncementWitnessEncode(chainHash: ByteVector32, shortChannelId: ShortChannelId, nodeId1: PublicKey, nodeId2: PublicKey, bitcoinKey1: PublicKey, bitcoinKey2: PublicKey, features: ByteVector, unknownFields: ByteVector): ByteVector = + sha256(sha256(serializationResult(LightningMessageCodecs.channelAnnouncementWitnessCodec.encode(features :: chainHash :: shortChannelId :: nodeId1 :: nodeId2 :: bitcoinKey1 :: bitcoinKey2 :: unknownFields :: HNil)))) - def nodeAnnouncementWitnessEncode(timestamp: Long, nodeId: PublicKey, rgbColor: Color, alias: String, features: ByteVector, addresses: List[NodeAddress]): ByteVector = - sha256(sha256(serializationResult(LightningMessageCodecs.nodeAnnouncementWitnessCodec.encode(features :: timestamp :: nodeId :: rgbColor :: alias :: addresses :: HNil)))) + def nodeAnnouncementWitnessEncode(timestamp: Long, nodeId: PublicKey, rgbColor: Color, alias: String, features: ByteVector, addresses: List[NodeAddress], unknownFields: ByteVector): ByteVector = + sha256(sha256(serializationResult(LightningMessageCodecs.nodeAnnouncementWitnessCodec.encode(features :: timestamp :: nodeId :: rgbColor :: alias :: addresses :: unknownFields :: HNil)))) - def channelUpdateWitnessEncode(chainHash: ByteVector32, shortChannelId: ShortChannelId, timestamp: Long, messageFlags: Byte, channelFlags: Byte, cltvExpiryDelta: Int, htlcMinimumMsat: Long, feeBaseMsat: Long, feeProportionalMillionths: Long, htlcMaximumMsat: Option[Long]): ByteVector = - sha256(sha256(serializationResult(LightningMessageCodecs.channelUpdateWitnessCodec.encode(chainHash :: shortChannelId :: timestamp :: messageFlags :: channelFlags :: cltvExpiryDelta :: htlcMinimumMsat :: feeBaseMsat :: feeProportionalMillionths :: htlcMaximumMsat :: HNil)))) + def channelUpdateWitnessEncode(chainHash: ByteVector32, shortChannelId: ShortChannelId, timestamp: Long, messageFlags: Byte, channelFlags: Byte, cltvExpiryDelta: Int, htlcMinimumMsat: Long, feeBaseMsat: Long, feeProportionalMillionths: Long, htlcMaximumMsat: Option[Long], unknownFields: ByteVector): ByteVector = + sha256(sha256(serializationResult(LightningMessageCodecs.channelUpdateWitnessCodec.encode(chainHash :: shortChannelId :: timestamp :: messageFlags :: channelFlags :: cltvExpiryDelta :: htlcMinimumMsat :: feeBaseMsat :: feeProportionalMillionths :: htlcMaximumMsat :: unknownFields :: HNil)))) def signChannelAnnouncement(chainHash: ByteVector32, shortChannelId: ShortChannelId, localNodeSecret: PrivateKey, remoteNodeId: PublicKey, localFundingPrivKey: PrivateKey, remoteFundingKey: PublicKey, features: ByteVector): (ByteVector64, ByteVector64) = { val witness = if (isNode1(localNodeSecret.publicKey, remoteNodeId)) { - channelAnnouncementWitnessEncode(chainHash, shortChannelId, localNodeSecret.publicKey, remoteNodeId, localFundingPrivKey.publicKey, remoteFundingKey, features) + channelAnnouncementWitnessEncode(chainHash, shortChannelId, localNodeSecret.publicKey, remoteNodeId, localFundingPrivKey.publicKey, remoteFundingKey, features, unknownFields = ByteVector.empty) } else { - channelAnnouncementWitnessEncode(chainHash, shortChannelId, remoteNodeId, localNodeSecret.publicKey, remoteFundingKey, localFundingPrivKey.publicKey, features) + channelAnnouncementWitnessEncode(chainHash, shortChannelId, remoteNodeId, localNodeSecret.publicKey, remoteFundingKey, localFundingPrivKey.publicKey, features, unknownFields = ByteVector.empty) } val nodeSig = Crypto.sign(witness, localNodeSecret) val bitcoinSig = Crypto.sign(witness, localFundingPrivKey) @@ -76,7 +76,7 @@ object Announcements { def makeNodeAnnouncement(nodeSecret: PrivateKey, alias: String, color: Color, nodeAddresses: List[NodeAddress], timestamp: Long = Platform.currentTime.milliseconds.toSeconds): NodeAnnouncement = { require(alias.size <= 32) - val witness = nodeAnnouncementWitnessEncode(timestamp, nodeSecret.publicKey, color, alias, ByteVector.empty, nodeAddresses) + val witness = nodeAnnouncementWitnessEncode(timestamp, nodeSecret.publicKey, color, alias, ByteVector.empty, nodeAddresses, unknownFields = ByteVector.empty) val sig = Crypto.sign(witness, nodeSecret) NodeAnnouncement( signature = sig, @@ -135,7 +135,7 @@ object Announcements { val channelFlags = makeChannelFlags(isNode1 = isNode1(nodeSecret.publicKey, remoteNodeId), enable = enable) val htlcMaximumMsatOpt = Some(htlcMaximumMsat) - val witness = channelUpdateWitnessEncode(chainHash, shortChannelId, timestamp, messageFlags, channelFlags, cltvExpiryDelta, htlcMinimumMsat, feeBaseMsat, feeProportionalMillionths, htlcMaximumMsatOpt) + val witness = channelUpdateWitnessEncode(chainHash, shortChannelId, timestamp, messageFlags, channelFlags, cltvExpiryDelta, htlcMinimumMsat, feeBaseMsat, feeProportionalMillionths, htlcMaximumMsatOpt, unknownFields = ByteVector.empty) val sig = Crypto.sign(witness, nodeSecret) ChannelUpdate( signature = sig, @@ -153,7 +153,7 @@ object Announcements { } def checkSigs(ann: ChannelAnnouncement): Boolean = { - val witness = channelAnnouncementWitnessEncode(ann.chainHash, ann.shortChannelId, ann.nodeId1, ann.nodeId2, ann.bitcoinKey1, ann.bitcoinKey2, ann.features) + val witness = channelAnnouncementWitnessEncode(ann.chainHash, ann.shortChannelId, ann.nodeId1, ann.nodeId2, ann.bitcoinKey1, ann.bitcoinKey2, ann.features, ann.unknownFields) verifySignature(witness, ann.nodeSignature1, ann.nodeId1) && verifySignature(witness, ann.nodeSignature2, ann.nodeId2) && verifySignature(witness, ann.bitcoinSignature1, ann.bitcoinKey1) && @@ -161,12 +161,12 @@ object Announcements { } def checkSig(ann: NodeAnnouncement): Boolean = { - val witness = nodeAnnouncementWitnessEncode(ann.timestamp, ann.nodeId, ann.rgbColor, ann.alias, ann.features, ann.addresses) + val witness = nodeAnnouncementWitnessEncode(ann.timestamp, ann.nodeId, ann.rgbColor, ann.alias, ann.features, ann.addresses, ann.unknownFields) verifySignature(witness, ann.signature, ann.nodeId) } def checkSig(upd: ChannelUpdate, nodeId: PublicKey): Boolean = { - val witness = channelUpdateWitnessEncode(upd.chainHash, upd.shortChannelId, upd.timestamp, upd.messageFlags, upd.channelFlags, upd.cltvExpiryDelta, upd.htlcMinimumMsat, upd.feeBaseMsat, upd.feeProportionalMillionths, upd.htlcMaximumMsat) + val witness = channelUpdateWitnessEncode(upd.chainHash, upd.shortChannelId, upd.timestamp, upd.messageFlags, upd.channelFlags, upd.cltvExpiryDelta, upd.htlcMinimumMsat, upd.feeBaseMsat, upd.feeProportionalMillionths, upd.htlcMaximumMsat, upd.unknownFields) verifySignature(witness, upd.signature, nodeId) } } diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/ChannelCodecs.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/ChannelCodecs.scala index 667b303b5a..1896db84d7 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/ChannelCodecs.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/ChannelCodecs.scala @@ -127,8 +127,8 @@ object ChannelCodecs extends Logging { val sig64OrDERCodec: Codec[ByteVector64] = Codec[ByteVector64]( (value: ByteVector64) => bytes(64).encode(value), (wire: BitVector) => bytes.decode(wire).map(_.map { - case bin64 if bin64.size == 64 => ByteVector64(bin64) - case der => Crypto.der2compact(der) + case bin64 if bin64.size == 64 => ByteVector64(bin64) + case der => Crypto.der2compact(der) }) ) @@ -266,12 +266,37 @@ object ChannelCodecs extends Logging { ("shortChannelId" | shortchannelid) :: ("lastSent" | fundingLockedCodec)).as[DATA_WAIT_FOR_FUNDING_LOCKED] + // All channel_announcement's written prior to supporting unknown trailing fields had the same fixed size, because + // those are the announcements that *we* created and we always used an empty features field, which was the only + // variable-length field. + val noUnknownFieldsChannelAnnouncementSizeCodec: Codec[Int] = provide(430) + + // We used to ignore unknown trailing fields, and assume that channel_update size was known. This is not true anymore, + // so we need to tell the codec where to stop, otherwise all the remaining part of the data will be decoded as unknown + // fields. Fortunately, we can easily tell what size the channel_update will be. + val noUnknownFieldsChannelUpdateSizeCodec: Codec[Int] = peek( // we need to take a peek at a specific byte to know what size the message will be, and then rollback to read the full message + ignore(8 * (64 + 32 + 8 + 4)) ~> // we skip the first fields: signature + chain_hash + short_channel_id + timestamp + byte // this is the messageFlags byte + ) + .map(messageFlags => if ((messageFlags & 1) != 0) 136 else 128) // depending on the value of option_channel_htlc_max, size will be 128B or 136B + .decodeOnly // this is for compat, we only need to decode + + // this is a decode-only codec compatible with versions 9afb26e and below + val DATA_NORMAL_COMPAT_03_Codec: Codec[DATA_NORMAL] = ( + ("commitments" | commitmentsCodec) :: + ("shortChannelId" | shortchannelid) :: + ("buried" | bool) :: + ("channelAnnouncement" | optional(bool, variableSizeBytes(noUnknownFieldsChannelAnnouncementSizeCodec, channelAnnouncementCodec))) :: + ("channelUpdate" | variableSizeBytes(noUnknownFieldsChannelUpdateSizeCodec, channelUpdateCodec)) :: + ("localShutdown" | optional(bool, shutdownCodec)) :: + ("remoteShutdown" | optional(bool, shutdownCodec))).as[DATA_NORMAL].decodeOnly + val DATA_NORMAL_Codec: Codec[DATA_NORMAL] = ( ("commitments" | commitmentsCodec) :: ("shortChannelId" | shortchannelid) :: ("buried" | bool) :: - ("channelAnnouncement" | optional(bool, channelAnnouncementCodec)) :: - ("channelUpdate" | channelUpdateCodec) :: + ("channelAnnouncement" | optional(bool, variableSizeBytes(uint16, channelAnnouncementCodec))) :: + ("channelUpdate" | variableSizeBytes(uint16, channelUpdateCodec)) :: ("localShutdown" | optional(bool, shutdownCodec)) :: ("remoteShutdown" | optional(bool, shutdownCodec))).as[DATA_NORMAL] @@ -329,11 +354,12 @@ object ChannelCodecs extends Logging { * More info here: https://github.com/scodec/scodec/issues/122 */ val stateDataCodec: Codec[HasCommitments] = ("version" | constant(0x00)) ~> discriminated[HasCommitments].by(uint16) + .typecase(0x10, DATA_NORMAL_Codec) .typecase(0x09, DATA_CLOSING_Codec) .typecase(0x08, DATA_WAIT_FOR_FUNDING_CONFIRMED_Codec) .typecase(0x01, DATA_WAIT_FOR_FUNDING_CONFIRMED_COMPAT_01_Codec) .typecase(0x02, DATA_WAIT_FOR_FUNDING_LOCKED_Codec) - .typecase(0x03, DATA_NORMAL_Codec) + .typecase(0x03, DATA_NORMAL_COMPAT_03_Codec) .typecase(0x04, DATA_SHUTDOWN_Codec) .typecase(0x05, DATA_NEGOTIATING_Codec) .typecase(0x06, DATA_CLOSING_COMPAT_06_Codec) diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/LightningMessageCodecs.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/LightningMessageCodecs.scala index 468573788a..132576af7f 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/LightningMessageCodecs.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/LightningMessageCodecs.scala @@ -16,11 +16,19 @@ package fr.acinq.eclair.wire +import java.net.{Inet4Address, Inet6Address, InetAddress} + +import fr.acinq.bitcoin.Crypto.{PrivateKey, PublicKey} +import fr.acinq.bitcoin.{ByteVector32, ByteVector64} import fr.acinq.eclair.crypto.Sphinx import fr.acinq.eclair.wire import fr.acinq.eclair.wire.CommonCodecs._ import scodec.bits.ByteVector import scodec.codecs._ +import scodec.{Attempt, Codec, Err} + +import scala.util.{Failure, Success, Try} + import scodec.Codec /** @@ -154,13 +162,15 @@ object LightningMessageCodecs { ("nodeSignature" | bytes64) :: ("bitcoinSignature" | bytes64)).as[AnnouncementSignatures] - val channelAnnouncementWitnessCodec = ("features" | varsizebinarydata) :: - ("chainHash" | bytes32) :: - ("shortChannelId" | shortchannelid) :: - ("nodeId1" | publicKey) :: - ("nodeId2" | publicKey) :: - ("bitcoinKey1" | publicKey) :: - ("bitcoinKey2" | publicKey) + val channelAnnouncementWitnessCodec = + ("features" | varsizebinarydata) :: + ("chainHash" | bytes32) :: + ("shortChannelId" | shortchannelid) :: + ("nodeId1" | publicKey) :: + ("nodeId2" | publicKey) :: + ("bitcoinKey1" | publicKey) :: + ("bitcoinKey2" | publicKey) :: + ("unknownFields" | bytes) val channelAnnouncementCodec: Codec[ChannelAnnouncement] = ( ("nodeSignature1" | bytes64) :: @@ -169,17 +179,19 @@ object LightningMessageCodecs { ("bitcoinSignature2" | bytes64) :: channelAnnouncementWitnessCodec).as[ChannelAnnouncement] - val nodeAnnouncementWitnessCodec = ("features" | varsizebinarydata) :: - ("timestamp" | uint32) :: - ("nodeId" | publicKey) :: - ("rgbColor" | rgb) :: - ("alias" | zeropaddedstring(32)) :: - ("addresses" | listofnodeaddresses) + val nodeAnnouncementWitnessCodec = + ("features" | varsizebinarydata) :: + ("timestamp" | uint32) :: + ("nodeId" | publicKey) :: + ("rgbColor" | rgb) :: + ("alias" | zeropaddedstring(32)) :: + ("addresses" | listofnodeaddresses) :: + ("unknownFields" | bytes) val nodeAnnouncementCodec: Codec[NodeAnnouncement] = ( ("signature" | bytes64) :: nodeAnnouncementWitnessCodec).as[NodeAnnouncement] - + val channelUpdateWitnessCodec = ("chainHash" | bytes32) :: ("shortChannelId" | shortchannelid) :: @@ -190,7 +202,8 @@ object LightningMessageCodecs { ("htlcMinimumMsat" | uint64overflow) :: ("feeBaseMsat" | uint32) :: ("feeProportionalMillionths" | uint32) :: - ("htlcMaximumMsat" | conditional((messageFlags & 1) != 0, uint64overflow)) + ("htlcMaximumMsat" | conditional((messageFlags & 1) != 0, uint64overflow)) :: + ("unknownFields" | bytes) }) val channelUpdateCodec: Codec[ChannelUpdate] = ( diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/LightningMessageTypes.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/LightningMessageTypes.scala index 9cf827eb54..0e4aef640a 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/LightningMessageTypes.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/LightningMessageTypes.scala @@ -164,7 +164,8 @@ case class ChannelAnnouncement(nodeSignature1: ByteVector64, nodeId1: PublicKey, nodeId2: PublicKey, bitcoinKey1: PublicKey, - bitcoinKey2: PublicKey) extends RoutingMessage with HasChainHash + bitcoinKey2: PublicKey, + unknownFields: ByteVector = ByteVector.empty) extends RoutingMessage with HasChainHash case class Color(r: Byte, g: Byte, b: Byte) { override def toString: String = f"#$r%02x$g%02x$b%02x" // to hexa s"# ${r}%02x ${r & 0xFF}${g & 0xFF}${b & 0xFF}" @@ -206,7 +207,8 @@ case class NodeAnnouncement(signature: ByteVector64, nodeId: PublicKey, rgbColor: Color, alias: String, - addresses: List[NodeAddress]) extends RoutingMessage with HasTimestamp + addresses: List[NodeAddress], + unknownFields: ByteVector = ByteVector.empty) extends RoutingMessage with HasTimestamp case class ChannelUpdate(signature: ByteVector64, chainHash: ByteVector32, @@ -218,7 +220,8 @@ case class ChannelUpdate(signature: ByteVector64, htlcMinimumMsat: Long, feeBaseMsat: Long, feeProportionalMillionths: Long, - htlcMaximumMsat: Option[Long]) extends RoutingMessage with HasTimestamp with HasChainHash { + htlcMaximumMsat: Option[Long], + unknownFields: ByteVector = ByteVector.empty) extends RoutingMessage with HasTimestamp with HasChainHash { require(((messageFlags & 1) != 0) == htlcMaximumMsat.isDefined, "htlcMaximumMsat is not consistent with messageFlags") } diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/db/BackupHandlerSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/db/BackupHandlerSpec.scala index 52365bc0ce..9ccb2f6dc1 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/db/BackupHandlerSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/db/BackupHandlerSpec.scala @@ -24,6 +24,7 @@ import akka.actor.{ActorSystem, Props} import akka.testkit.{TestKit, TestProbe} import fr.acinq.eclair.channel.ChannelPersisted import fr.acinq.eclair.db.sqlite.SqliteChannelsDb +import fr.acinq.eclair.wire.ChannelCodecsSpec import fr.acinq.eclair.{TestConstants, TestUtils, randomBytes32} import org.scalatest.FunSuiteLike @@ -35,7 +36,7 @@ class BackupHandlerSpec extends TestKit(ActorSystem("test")) with FunSuiteLike { val dest = new File(TestUtils.BUILD_DIRECTORY, s"backup-${UUID.randomUUID()}") wip.deleteOnExit() dest.deleteOnExit() - val channel = ChannelStateSpec.normal + val channel = ChannelCodecsSpec.normal db.channels.addOrUpdateChannel(channel) assert(db.channels.listLocalChannels() == Seq(channel)) diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/db/ChannelStateSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/db/ChannelStateSpec.scala deleted file mode 100644 index 4b1bc6427d..0000000000 --- a/eclair-core/src/test/scala/fr/acinq/eclair/db/ChannelStateSpec.scala +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2019 ACINQ SAS - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package fr.acinq.eclair.db - -import java.util.UUID - -import fr.acinq.bitcoin.Crypto.{PrivateKey} -import fr.acinq.bitcoin.{Block, ByteVector32, Crypto, DeterministicWallet, MilliSatoshi, Satoshi, Transaction} -import fr.acinq.eclair.channel.Helpers.Funding -import fr.acinq.eclair.channel._ -import fr.acinq.eclair.crypto.{LocalKeyManager, ShaChain, Sphinx} -import fr.acinq.eclair.payment.{Local, Relayed} -import fr.acinq.eclair.router.Announcements -import fr.acinq.eclair.transactions.Transactions.CommitTx -import fr.acinq.eclair.transactions._ -import fr.acinq.eclair.wire.{ChannelCodecs, UpdateAddHtlc} -import fr.acinq.eclair.{ShortChannelId, UInt64, randomKey} -import org.scalatest.FunSuite -import scodec.bits._ - -import scala.io.Source - -/** - * Created by fabrice on 07/02/17. - */ - -class ChannelStateSpec extends FunSuite { - - import ChannelStateSpec._ - - test("basic serialization test (NORMAL)") { - val data = normal - val bin = ChannelCodecs.DATA_NORMAL_Codec.encode(data).require - val check = ChannelCodecs.DATA_NORMAL_Codec.decodeValue(bin).require - assert(data.commitments.localCommit.spec === check.commitments.localCommit.spec) - assert(data === check) - } - - test("nonreg") { - val bin = ByteVector.fromValidHex(Source.fromInputStream(getClass.getResourceAsStream("/normal_data_htlcs.bin")).mkString) - val c = ChannelCodecs.stateDataCodec.decode(bin.toBitVector).require.value - - val ref = Seq( - (hex"30440220104aed8d52fe50e2313a9a456607838a0cdac75fdc37afe581c415e7a20da944022034d1ac69c64f34571251be8cc6b50116f26453813267fb9afa3e318a79f4f32401", hex"304502210097fcda40b22916b5d61badedf6126658c2b5927d5002cc2c3e5f88a78ba5f45b02204a74bcf8827d894cab153fc051f39d8e2aeb660162a6a05797f7140587a6133301"), - (hex"30450221009e0e57886b81fd4159f672728891d799203b23c351e93134aba445b288443d3502207b77faa4227126b7d087144c75f4e5c8af9db705b37806dbd2d3f4339666d32201", hex"3045022100aa403fa23e82379a16ba16b446dbdee5a4f879ba690ad3f4f10dc445df2832ba022000a51fdbdb69dcbd5518274303fcece60d719cb6d593e882fdb0190253bbaaab01"), - (hex"3045022100fb44e66fc294d9ece2c33465398221edcfd857208d32a36dedab9906d00b356d022008c5fcfa7b41f8616d57ed009a8614aca636edae1479b6114e03407ba6fceea701", hex"3045022100a9ad65dada5e5500897173bca610135a13008895ce445fbc90d440d5406bd6150220644d75e5ca774ef6b559ffaf1083a9a5da250c3c87666d96daf35b480ef0c65701"), - (hex"3044022009e4f39656dc8712863bffe2acdfa4d2245f65f38a230dd034b226dc2e5fd7ce022049c0108e44c399d1a1b67ab6f60566f491d8682406ac4a03a914f9a21196d6ba01", hex"3044022063a6839c031fd5534d7807a8fff8ca0f9a72d8aa9d78ee104d6ece2b417ac5ce0220193d9b521a44011d31d2bb85be5043119c42a7aee3d9ef68b7388c3c9c3a780501"), - (hex"304402207eaf435948b9e04cb6551f97ee5d85ac879e20d3fae3f5c9a0880ef452d32ac902206e9c5c9098c3e3bef010d3142578823c7fb43b43fe0a0036d481f18a0168b20f01", hex"304402205dda44c9d8aaf37a6f5f6c99713d2a001682f2593a960ccaf5c23059cd20016b02200991b09bccdfc87918852650a4bfa7b4ac9028101362631b5ec376427084138e01"), - (hex"304402200232dbb9d46dabc6569f3f65f4f2a4b7e5acf7be85687b9897141e9784cb9d370220087b2c1dda444d7351976135b56f2f2ca22d8c03d5aa40acbce8c4241daf541501", hex"3045022100eddaa4f767bc70fd672bee983b1644dbff9479def0efc7cca79f0daa1bad370d02204c810238968ae9e86b99d348464e9ac7a06e40225022ae4203ae36fad928c22401"), - (hex"3045022100daa604934db542aa5a9bcbd48eb666fac8acdee92ccd8d42228f52377c51184a022069f855477b27cec39b15fb9e666c09b6c4860c8b80cd1315d2498d97d9cf024601", hex"3044022020e6d43dee03f54574d8245edf2e312d0a492dd2350b7f8df68390b8876de5640220555d46cd545ff0ecc280e6bc82e976ff494bab5f2b128807626753ffb9e5796e01"), - (hex"3044022046c3cf88f9e8639c954c584725482dd6e6403deda3824c37ae95db9bf99d341602206432f76c5ca3d61951155c1b223fd35dd4227f83e1ff9a93437b63515567d23f01", hex"3045022100812a360a6ddc44179f80e5b4252bca74bb5dbe1da25230c9e8afcd388a2fd64702202e45a658123f0263ca1157ef9a9995ede1625d1ecba532957185f1d8044aa1d301"), - (hex"30440220482df018e51b4f684271682bc3c81c481d288d61000a77df2126afe042c3471d02204772720ff1ea323a271259022a0458ae4d228e5f613ade63fca38eb5d443756a01", hex"3044022076a338d225b8954412198ce5936aaa6433da1f51dd9bcbe69d95a1e0960c169802207db267517fc73e358e09f4c89313ae17ed4d5f6d8432faec9ec1e784a2a7da7c01"), - (hex"3045022100916255b5758d66cd46f653f8a5a71b1c857bfae1a7cf85195b5d78476c4138c502200101e3ec9874aa2644691662bf8945a182af1237bb61c459e9dbff495b9097d001", hex"304402201d099a464a7696b22a8e58b65c52e9a519a06a5c49e944155d4e5fbd14d3f5b902203c091c0ec5b840a80be739d29b5fc2c75cb94928e5ea83133f84d226f28cd4b701"), - (hex"3045022100d8eaa436faec6b38f155065893f1212ce43615fbec49b4af72f16119774b5472022033aa303992f4a8cfe1c77e6a0d2baa73baad0305a88da16d26122e536867431101", hex"304402203af7b7ea16cc018fdb414f52cd38ed548dc257cbb06c812c9dc1d60500b21485022072cd74b7e49bfd813e09bae778da903b44b7b0ae22b87af4c34cf8bb77dfdef201"), - (hex"304402204f5dd042bfb449c522012a2d461e5a94c9ea3be629c0ab091b0e1f5569eb119c022021411ff8affabab12cd39f0eaa64f1b08fa72ada6f37d1d46c6bde4483d869fb01", hex"3044022043573edb37be815d1b97b90803f601dfc91c25279ccda606ad6515fee721fe57022030ac2883408a2075a47337443eb539062a8ac6b5453befb2b9863d697e35dd8201"), - (hex"3044022030ff3d4d42ef1c3d742164a30ff7b021215e881d9277a52a1720514a4473289502204b090f6b412e8caacb5bcbf295babb075d9d5490e3f7678c289206780f6f0bc901", hex"304502210093fd7dfa3ef6cdf5b94cfadf83022be98062d53cd7097a73947453b210a481eb0220622e63a21b787ea7bb55f01ab6fe503fcb8ef4cb65adce7a264ae014403646fe01") - ) - - val sigs = c.commitments - .localCommit - .publishableTxs - .htlcTxsAndSigs - .map(data => (Scripts.der(data.localSig), Scripts.der(data.remoteSig))) - - assert(ref === sigs) - } -} - -object ChannelStateSpec { - val keyManager = new LocalKeyManager(ByteVector32(ByteVector.fill(32)(1)), Block.RegtestGenesisBlock.hash) - val localParams = LocalParams( - keyManager.nodeId, - channelKeyPath = DeterministicWallet.KeyPath(Seq(42L)), - dustLimitSatoshis = Satoshi(546).toLong, - maxHtlcValueInFlightMsat = UInt64(50000000), - channelReserveSatoshis = 10000, - htlcMinimumMsat = 10000, - toSelfDelay = 144, - maxAcceptedHtlcs = 50, - defaultFinalScriptPubKey = ByteVector.empty, - isFunder = true, - globalFeatures = hex"dead", - localFeatures = hex"beef") - - val remoteParams = RemoteParams( - nodeId = randomKey.publicKey, - dustLimitSatoshis = Satoshi(546).toLong, - maxHtlcValueInFlightMsat = UInt64(5000000), - channelReserveSatoshis = 10000, - htlcMinimumMsat = 5000, - toSelfDelay = 144, - maxAcceptedHtlcs = 50, - fundingPubKey = PrivateKey(ByteVector32(ByteVector.fill(32)(1)) :+ 1.toByte).publicKey, - revocationBasepoint = PrivateKey(ByteVector.fill(32)(2)).publicKey, - paymentBasepoint = PrivateKey(ByteVector.fill(32)(3)).publicKey, - delayedPaymentBasepoint = PrivateKey(ByteVector.fill(32)(4)).publicKey, - htlcBasepoint = PrivateKey(ByteVector.fill(32)(6)).publicKey, - globalFeatures = hex"dead", - localFeatures = hex"beef") - - val paymentPreimages = Seq( - ByteVector32(hex"0000000000000000000000000000000000000000000000000000000000000000"), - ByteVector32(hex"0101010101010101010101010101010101010101010101010101010101010101"), - ByteVector32(hex"0202020202020202020202020202020202020202020202020202020202020202"), - ByteVector32(hex"0303030303030303030303030303030303030303030303030303030303030303"), - ByteVector32(hex"0404040404040404040404040404040404040404040404040404040404040404") - ) - - val htlcs = Seq( - DirectedHtlc(IN, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(1000000).amount, Crypto.sha256(paymentPreimages(0)), 500, ByteVector.fill(Sphinx.PacketLength)(0))), - DirectedHtlc(IN, UpdateAddHtlc(ByteVector32.Zeroes, 1, MilliSatoshi(2000000).amount, Crypto.sha256(paymentPreimages(1)), 501, ByteVector.fill(Sphinx.PacketLength)(0))), - DirectedHtlc(OUT, UpdateAddHtlc(ByteVector32.Zeroes, 30, MilliSatoshi(2000000).amount, Crypto.sha256(paymentPreimages(2)), 502, ByteVector.fill(Sphinx.PacketLength)(0))), - DirectedHtlc(OUT, UpdateAddHtlc(ByteVector32.Zeroes, 31, MilliSatoshi(3000000).amount, Crypto.sha256(paymentPreimages(3)), 503, ByteVector.fill(Sphinx.PacketLength)(0))), - DirectedHtlc(IN, UpdateAddHtlc(ByteVector32.Zeroes, 2, MilliSatoshi(4000000).amount, Crypto.sha256(paymentPreimages(4)), 504, ByteVector.fill(Sphinx.PacketLength)(0))) - ) - - val fundingTx = Transaction.read("0200000001adbb20ea41a8423ea937e76e8151636bf6093b70eaff942930d20576600521fd000000006b48304502210090587b6201e166ad6af0227d3036a9454223d49a1f11839c1a362184340ef0240220577f7cd5cca78719405cbf1de7414ac027f0239ef6e214c90fcaab0454d84b3b012103535b32d5eb0a6ed0982a0479bbadc9868d9836f6ba94dd5a63be16d875069184ffffffff028096980000000000220020c015c4a6be010e21657068fc2e6a9d02b27ebe4d490a25846f7237f104d1a3cd20256d29010000001600143ca33c2e4446f4a305f23c80df8ad1afdcf652f900000000") - val fundingAmount = fundingTx.txOut(0).amount - val commitmentInput = Funding.makeFundingInputInfo(fundingTx.hash, 0, fundingAmount, keyManager.fundingPublicKey(localParams.channelKeyPath).publicKey, remoteParams.fundingPubKey) - - val localCommit = LocalCommit(0, CommitmentSpec(htlcs.toSet, 1500, 50000000, 70000000), PublishableTxs(CommitTx(commitmentInput, Transaction(2, Nil, Nil, 0)), Nil)) - val remoteCommit = RemoteCommit(0, CommitmentSpec(htlcs.map(htlc => htlc.copy(direction = htlc.direction.opposite)).toSet, 1500, 50000, 700000), ByteVector32(hex"0303030303030303030303030303030303030303030303030303030303030303"), PrivateKey(ByteVector.fill(32)(4)).publicKey) - val commitments = Commitments(localParams, remoteParams, channelFlags = 0x01.toByte, localCommit, remoteCommit, LocalChanges(Nil, Nil, Nil), RemoteChanges(Nil, Nil, Nil), - localNextHtlcId = 32L, - remoteNextHtlcId = 4L, - originChannels = Map(42L -> Local(UUID.randomUUID, None), 15000L -> Relayed(ByteVector32(ByteVector.fill(32)(42)), 43, 11000000L, 10000000L)), - remoteNextCommitInfo = Right(randomKey.publicKey), - commitInput = commitmentInput, remotePerCommitmentSecrets = ShaChain.init, channelId = ByteVector32.Zeroes) - - val channelUpdate = Announcements.makeChannelUpdate(ByteVector32(ByteVector.fill(32)(1)), randomKey, randomKey.publicKey, ShortChannelId(142553), 42, 15, 575, 53, Channel.MAX_FUNDING_SATOSHIS * 1000L) - - val normal = DATA_NORMAL(commitments, ShortChannelId(42), true, None, channelUpdate, None, None) -} diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/db/SqliteAuditDbSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/db/SqliteAuditDbSpec.scala index 9758fdd3df..282841c3cc 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/db/SqliteAuditDbSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/db/SqliteAuditDbSpec.scala @@ -24,9 +24,10 @@ import fr.acinq.eclair.channel.{AvailableBalanceChanged, ChannelErrorOccured, Ne import fr.acinq.eclair.db.sqlite.SqliteAuditDb import fr.acinq.eclair.db.sqlite.SqliteUtils.{getVersion, using} import fr.acinq.eclair.payment.{PaymentReceived, PaymentRelayed, PaymentSent} -import fr.acinq.eclair.wire.ChannelCodecs +import fr.acinq.eclair.wire.{ChannelCodecs, ChannelCodecsSpec} import fr.acinq.eclair._ import org.scalatest.FunSuite + import concurrent.duration._ import scala.compat.Platform @@ -49,7 +50,7 @@ class SqliteAuditDbSpec extends FunSuite { val e4 = NetworkFeePaid(null, randomKey.publicKey, randomBytes32, Transaction(0, Seq.empty, Seq.empty, 0), Satoshi(42), "mutual") val e5 = PaymentSent(ChannelCodecs.UNKNOWN_UUID, MilliSatoshi(42000), MilliSatoshi(1000), randomBytes32, randomBytes32, randomBytes32, timestamp = 0) val e6 = PaymentSent(ChannelCodecs.UNKNOWN_UUID, MilliSatoshi(42000), MilliSatoshi(1000), randomBytes32, randomBytes32, randomBytes32, timestamp = (Platform.currentTime.milliseconds + 10.minutes).toMillis) - val e7 = AvailableBalanceChanged(null, randomBytes32, ShortChannelId(500000, 42, 1), 456123000, ChannelStateSpec.commitments) + val e7 = AvailableBalanceChanged(null, randomBytes32, ShortChannelId(500000, 42, 1), 456123000, ChannelCodecsSpec.commitments) val e8 = ChannelLifecycleEvent(randomBytes32, randomKey.publicKey, 456123000, true, false, "mutual") val e9 = ChannelErrorOccured(null, randomBytes32, randomKey.publicKey, null, LocalError(new RuntimeException("oops")), true) val e10 = ChannelErrorOccured(null, randomBytes32, randomKey.publicKey, null, RemoteError(wire.Error(randomBytes32, "remote oops")), true) diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/db/SqliteChannelsDbSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/db/SqliteChannelsDbSpec.scala index e80273ecf5..88052c3158 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/db/SqliteChannelsDbSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/db/SqliteChannelsDbSpec.scala @@ -21,6 +21,7 @@ import fr.acinq.eclair.TestConstants import fr.acinq.eclair.db.sqlite.SqliteUtils.{getVersion, using} import fr.acinq.eclair.db.sqlite.{SqliteChannelsDb, SqlitePendingRelayDb} import fr.acinq.eclair.wire.ChannelCodecs.stateDataCodec +import fr.acinq.eclair.wire.ChannelCodecsSpec import org.scalatest.FunSuite import org.sqlite.SQLiteException import scodec.bits.ByteVector @@ -39,7 +40,7 @@ class SqliteChannelsDbSpec extends FunSuite { val db = new SqliteChannelsDb(sqlite) new SqlitePendingRelayDb(sqlite) // needed by db.removeChannel - val channel = ChannelStateSpec.normal + val channel = ChannelCodecsSpec.normal val commitNumber = 42 val paymentHash1 = ByteVector32.Zeroes @@ -78,7 +79,7 @@ class SqliteChannelsDbSpec extends FunSuite { } // insert 1 row - val channel = ChannelStateSpec.normal + val channel = ChannelCodecsSpec.normal val data = stateDataCodec.encode(channel).require.toByteArray using(sqlite.prepareStatement("INSERT INTO local_channels VALUES (?, ?)")) { statement => statement.setBytes(1, channel.channelId.toArray) diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/io/HtlcReaperSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/io/HtlcReaperSpec.scala index 63765733c9..c1197b1214 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/io/HtlcReaperSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/io/HtlcReaperSpec.scala @@ -19,9 +19,8 @@ package fr.acinq.eclair.io import akka.actor.{ActorSystem, Props} import akka.testkit.{TestKit, TestProbe} import fr.acinq.eclair.channel._ -import fr.acinq.eclair.db.ChannelStateSpec import fr.acinq.eclair.randomBytes32 -import fr.acinq.eclair.wire.{TemporaryNodeFailure, UpdateAddHtlc} +import fr.acinq.eclair.wire.{ChannelCodecsSpec, TemporaryNodeFailure, UpdateAddHtlc} import org.scalatest.FunSuiteLike import scodec.bits.ByteVector @@ -35,7 +34,7 @@ class HtlcReaperSpec extends TestKit(ActorSystem("test")) with FunSuiteLike { test("init and cleanup") { - val data = ChannelStateSpec.normal + val data = ChannelCodecsSpec.normal // assuming that data has incoming htlcs 0 and 1, we don't care about the amount/payment_hash/onion fields val add0 = UpdateAddHtlc(data.channelId, 0, 20000, randomBytes32, 100, ByteVector.empty) diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala index 51969071f3..82617ea236 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/io/PeerSpec.scala @@ -16,12 +16,10 @@ package fr.acinq.eclair.io -import java.net.{Inet4Address, InetSocketAddress} - -import akka.actor.{ActorRef, PoisonPill, Terminated} import java.net.{Inet4Address, InetAddress, InetSocketAddress, ServerSocket} -import akka.actor.{ActorRef, ActorSystem, PoisonPill} + import akka.actor.FSM.{CurrentState, SubscribeTransitionCallBack, Transition} +import akka.actor.{ActorRef, PoisonPill} import akka.testkit.{TestFSMRef, TestProbe} import fr.acinq.bitcoin.Crypto.PublicKey import fr.acinq.eclair.TestConstants._ @@ -29,13 +27,13 @@ import fr.acinq.eclair._ import fr.acinq.eclair.blockchain.EclairWallet import fr.acinq.eclair.channel.HasCommitments import fr.acinq.eclair.crypto.TransportHandler -import fr.acinq.eclair.db.ChannelStateSpec import fr.acinq.eclair.io.Peer._ import fr.acinq.eclair.router.RoutingSyncSpec.makeFakeRoutingInfo import fr.acinq.eclair.router.{ChannelRangeQueries, ChannelRangeQueriesSpec, Rebroadcast} -import fr.acinq.eclair.wire.{Color, Error, IPv4, NodeAddress, NodeAnnouncement, Ping, Pong} +import fr.acinq.eclair.wire.{ChannelCodecsSpec, Color, Error, IPv4, NodeAddress, NodeAnnouncement, Ping, Pong} import org.scalatest.{Outcome, Tag} import scodec.bits.ByteVector + import scala.concurrent.duration._ class PeerSpec extends TestkitBaseClass { @@ -90,7 +88,7 @@ class PeerSpec extends TestkitBaseClass { test("restore existing channels") { f => import f._ val probe = TestProbe() - connect(remoteNodeId, authenticator, watcher, router, relayer, connection, transport, peer, channels = Set(ChannelStateSpec.normal)) + connect(remoteNodeId, authenticator, watcher, router, relayer, connection, transport, peer, channels = Set(ChannelCodecsSpec.normal)) probe.send(peer, Peer.GetPeerInfo) probe.expectMsg(PeerInfo(remoteNodeId, "CONNECTED", Some(fakeIPAddress.socketAddress), 1)) } @@ -138,7 +136,7 @@ class PeerSpec extends TestkitBaseClass { test("ignore reconnect (no known address)") { f => import f._ val probe = TestProbe() - probe.send(peer, Peer.Init(None, Set(ChannelStateSpec.normal))) + probe.send(peer, Peer.Init(None, Set(ChannelCodecsSpec.normal))) probe.send(peer, Peer.Reconnect) probe.expectNoMsg() } @@ -157,13 +155,13 @@ class PeerSpec extends TestkitBaseClass { // we create a dummy tcp server and update bob's announcement to point to it val mockServer = new ServerSocket(0, 1, InetAddress.getLocalHost) // port will be assigned automatically - val mockAddress = NodeAddress.fromParts(mockServer.getInetAddress.getHostAddress, mockServer.getLocalPort).get + val mockAddress = NodeAddress.fromParts(mockServer.getInetAddress.getHostAddress, mockServer.getLocalPort).get val bobAnnouncement = NodeAnnouncement(randomBytes64, ByteVector.empty, 1, Bob.nodeParams.nodeId, Color(100.toByte, 200.toByte, 300.toByte), "node-alias", mockAddress :: Nil) peer.underlyingActor.nodeParams.db.network.addNode(bobAnnouncement) val probe = TestProbe() awaitCond(peer.stateName == INSTANTIATING) - probe.send(peer, Peer.Init(None, Set(ChannelStateSpec.normal))) + probe.send(peer, Peer.Init(None, Set(ChannelCodecsSpec.normal))) awaitCond(peer.stateName == DISCONNECTED) // we have auto-reconnect=false so we need to manually tell the peer to reconnect @@ -179,7 +177,7 @@ class PeerSpec extends TestkitBaseClass { import f._ val probe = TestProbe() val previouslyKnownAddress = new InetSocketAddress("1.2.3.4", 9735) - probe.send(peer, Peer.Init(Some(previouslyKnownAddress), Set(ChannelStateSpec.normal))) + probe.send(peer, Peer.Init(Some(previouslyKnownAddress), Set(ChannelCodecsSpec.normal))) probe.send(peer, Peer.Reconnect) val interval = (peer.underlyingActor.nodeParams.maxReconnectInterval.toSeconds / 2) to peer.underlyingActor.nodeParams.maxReconnectInterval.toSeconds awaitCond(interval contains peer.stateData.asInstanceOf[DisconnectedData].nextReconnectionDelay.toSeconds) @@ -188,7 +186,7 @@ class PeerSpec extends TestkitBaseClass { test("reconnect with increasing delays") { f => import f._ val probe = TestProbe() - connect(remoteNodeId, authenticator, watcher, router, relayer, connection, transport, peer, channels = Set(ChannelStateSpec.normal)) + connect(remoteNodeId, authenticator, watcher, router, relayer, connection, transport, peer, channels = Set(ChannelCodecsSpec.normal)) probe.send(transport.ref, PoisonPill) awaitCond(peer.stateName === DISCONNECTED) assert(peer.stateData.asInstanceOf[DisconnectedData].nextReconnectionDelay === (10 seconds)) @@ -216,7 +214,7 @@ class PeerSpec extends TestkitBaseClass { import f._ val probe = TestProbe() - probe.send(peer, Peer.Init(None, Set(ChannelStateSpec.normal))) + probe.send(peer, Peer.Init(None, Set(ChannelCodecsSpec.normal))) authenticator.send(peer, Authenticator.Authenticated(connection.ref, transport.ref, remoteNodeId, fakeIPAddress.socketAddress, outgoing = true, None)) probe.send(peer, Peer.GetPeerInfo) @@ -230,7 +228,7 @@ class PeerSpec extends TestkitBaseClass { import f._ val probe = TestProbe() - connect(remoteNodeId, authenticator, watcher, router, relayer, connection, transport, peer, channels = Set(ChannelStateSpec.normal)) + connect(remoteNodeId, authenticator, watcher, router, relayer, connection, transport, peer, channels = Set(ChannelCodecsSpec.normal)) probe.send(peer, Peer.GetPeerInfo) assert(probe.expectMsgType[Peer.PeerInfo].state == "CONNECTED") diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/io/SwitchboardSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/io/SwitchboardSpec.scala index 0af0579f40..ca78e81b99 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/io/SwitchboardSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/io/SwitchboardSpec.scala @@ -2,14 +2,14 @@ package fr.acinq.eclair.io import java.io.File -import akka.actor.{ActorRef, ActorSystem, Props} +import akka.actor.{ActorRef, ActorSystem} import akka.testkit.{TestKit, TestProbe} import fr.acinq.bitcoin.ByteVector64 import fr.acinq.bitcoin.Crypto.PublicKey import fr.acinq.eclair.TestConstants._ import fr.acinq.eclair.blockchain.TestWallet import fr.acinq.eclair.db._ -import fr.acinq.eclair.wire.{Color, NodeAddress, NodeAnnouncement} +import fr.acinq.eclair.wire.{ChannelCodecsSpec, Color, NodeAddress, NodeAnnouncement} import org.mockito.scalatest.IdiomaticMockito import org.scalatest.FunSuiteLike import scodec.bits._ @@ -31,7 +31,7 @@ class SwitchboardSpec extends TestKit(ActorSystem("test")) with FunSuiteLike wit } ) - val remoteNodeId = ChannelStateSpec.normal.commitments.remoteParams.nodeId + val remoteNodeId = ChannelCodecsSpec.normal.commitments.remoteParams.nodeId val authenticator = TestProbe() val watcher = TestProbe() val router = TestProbe() @@ -45,7 +45,7 @@ class SwitchboardSpec extends TestKit(ActorSystem("test")) with FunSuiteLike wit ) // add a channel to the db - nodeParams.db.channels.addOrUpdateChannel(ChannelStateSpec.normal) + nodeParams.db.channels.addOrUpdateChannel(ChannelCodecsSpec.normal) val switchboard = system.actorOf(Switchboard.props(nodeParams, authenticator.ref, watcher.ref, router.ref, relayer.ref, wallet)) diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/wire/ChannelCodecsSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/wire/ChannelCodecsSpec.scala index e6e6b1ddd7..c60f383553 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/wire/ChannelCodecsSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/wire/ChannelCodecsSpec.scala @@ -19,21 +19,28 @@ package fr.acinq.eclair.wire import java.util.UUID import akka.actor.ActorSystem +import fr.acinq.bitcoin.Crypto.PrivateKey import fr.acinq.bitcoin.DeterministicWallet.KeyPath -import fr.acinq.bitcoin.{DeterministicWallet, OutPoint} +import fr.acinq.bitcoin.{Block, ByteVector32, Crypto, DeterministicWallet, MilliSatoshi, OutPoint, Satoshi, Transaction} +import fr.acinq.eclair._ +import fr.acinq.eclair.api.JsonSupport +import fr.acinq.eclair.channel.Helpers.Funding import fr.acinq.eclair.channel._ -import fr.acinq.eclair.crypto.Sphinx +import fr.acinq.eclair.crypto.{LocalKeyManager, ShaChain, Sphinx} import fr.acinq.eclair.payment.{Local, Relayed} +import fr.acinq.eclair.router.Announcements +import fr.acinq.eclair.transactions.Transactions.CommitTx import fr.acinq.eclair.transactions._ import fr.acinq.eclair.wire.ChannelCodecs._ -import fr.acinq.eclair.{UInt64, randomBytes, randomBytes32, randomKey} +import org.json4s.jackson.Serialization import org.scalatest.FunSuite import scodec.bits._ +import scodec.{Attempt, DecodeResult} import scala.compat.Platform import scala.concurrent.duration._ +import scala.io.Source import scala.util.Random -import scala.concurrent.duration._ /** * Created by PM on 31/05/2016. @@ -41,6 +48,8 @@ import scala.concurrent.duration._ class ChannelCodecsSpec extends FunSuite { + import ChannelCodecsSpec._ + test("encode/decode key paths (all 0s)") { val keyPath = KeyPath(Seq(0L, 0L, 0L, 0L)) val encoded = keyPathCodec.encode(keyPath).require @@ -173,7 +182,44 @@ class ChannelCodecsSpec extends FunSuite { assert(spentMapCodec.decodeValue(spentMapCodec.encode(map).require).require === map) } - test("backwards compatibility DATA_WAIT_FOR_FUNDING_CONFIRMED") { + test("basic serialization test (NORMAL)") { + val data = normal + val bin = ChannelCodecs.DATA_NORMAL_Codec.encode(data).require + val check = ChannelCodecs.DATA_NORMAL_Codec.decodeValue(bin).require + assert(data.commitments.localCommit.spec === check.commitments.localCommit.spec) + assert(data === check) + } + + test("nonreg for der/bin64 signatures") { + val bin = ByteVector.fromValidHex(Source.fromInputStream(getClass.getResourceAsStream("/normal_data_htlcs.bin")).mkString) + val c = ChannelCodecs.stateDataCodec.decode(bin.toBitVector).require.value + + val ref = Seq( + (hex"30440220104aed8d52fe50e2313a9a456607838a0cdac75fdc37afe581c415e7a20da944022034d1ac69c64f34571251be8cc6b50116f26453813267fb9afa3e318a79f4f32401", hex"304502210097fcda40b22916b5d61badedf6126658c2b5927d5002cc2c3e5f88a78ba5f45b02204a74bcf8827d894cab153fc051f39d8e2aeb660162a6a05797f7140587a6133301"), + (hex"30450221009e0e57886b81fd4159f672728891d799203b23c351e93134aba445b288443d3502207b77faa4227126b7d087144c75f4e5c8af9db705b37806dbd2d3f4339666d32201", hex"3045022100aa403fa23e82379a16ba16b446dbdee5a4f879ba690ad3f4f10dc445df2832ba022000a51fdbdb69dcbd5518274303fcece60d719cb6d593e882fdb0190253bbaaab01"), + (hex"3045022100fb44e66fc294d9ece2c33465398221edcfd857208d32a36dedab9906d00b356d022008c5fcfa7b41f8616d57ed009a8614aca636edae1479b6114e03407ba6fceea701", hex"3045022100a9ad65dada5e5500897173bca610135a13008895ce445fbc90d440d5406bd6150220644d75e5ca774ef6b559ffaf1083a9a5da250c3c87666d96daf35b480ef0c65701"), + (hex"3044022009e4f39656dc8712863bffe2acdfa4d2245f65f38a230dd034b226dc2e5fd7ce022049c0108e44c399d1a1b67ab6f60566f491d8682406ac4a03a914f9a21196d6ba01", hex"3044022063a6839c031fd5534d7807a8fff8ca0f9a72d8aa9d78ee104d6ece2b417ac5ce0220193d9b521a44011d31d2bb85be5043119c42a7aee3d9ef68b7388c3c9c3a780501"), + (hex"304402207eaf435948b9e04cb6551f97ee5d85ac879e20d3fae3f5c9a0880ef452d32ac902206e9c5c9098c3e3bef010d3142578823c7fb43b43fe0a0036d481f18a0168b20f01", hex"304402205dda44c9d8aaf37a6f5f6c99713d2a001682f2593a960ccaf5c23059cd20016b02200991b09bccdfc87918852650a4bfa7b4ac9028101362631b5ec376427084138e01"), + (hex"304402200232dbb9d46dabc6569f3f65f4f2a4b7e5acf7be85687b9897141e9784cb9d370220087b2c1dda444d7351976135b56f2f2ca22d8c03d5aa40acbce8c4241daf541501", hex"3045022100eddaa4f767bc70fd672bee983b1644dbff9479def0efc7cca79f0daa1bad370d02204c810238968ae9e86b99d348464e9ac7a06e40225022ae4203ae36fad928c22401"), + (hex"3045022100daa604934db542aa5a9bcbd48eb666fac8acdee92ccd8d42228f52377c51184a022069f855477b27cec39b15fb9e666c09b6c4860c8b80cd1315d2498d97d9cf024601", hex"3044022020e6d43dee03f54574d8245edf2e312d0a492dd2350b7f8df68390b8876de5640220555d46cd545ff0ecc280e6bc82e976ff494bab5f2b128807626753ffb9e5796e01"), + (hex"3044022046c3cf88f9e8639c954c584725482dd6e6403deda3824c37ae95db9bf99d341602206432f76c5ca3d61951155c1b223fd35dd4227f83e1ff9a93437b63515567d23f01", hex"3045022100812a360a6ddc44179f80e5b4252bca74bb5dbe1da25230c9e8afcd388a2fd64702202e45a658123f0263ca1157ef9a9995ede1625d1ecba532957185f1d8044aa1d301"), + (hex"30440220482df018e51b4f684271682bc3c81c481d288d61000a77df2126afe042c3471d02204772720ff1ea323a271259022a0458ae4d228e5f613ade63fca38eb5d443756a01", hex"3044022076a338d225b8954412198ce5936aaa6433da1f51dd9bcbe69d95a1e0960c169802207db267517fc73e358e09f4c89313ae17ed4d5f6d8432faec9ec1e784a2a7da7c01"), + (hex"3045022100916255b5758d66cd46f653f8a5a71b1c857bfae1a7cf85195b5d78476c4138c502200101e3ec9874aa2644691662bf8945a182af1237bb61c459e9dbff495b9097d001", hex"304402201d099a464a7696b22a8e58b65c52e9a519a06a5c49e944155d4e5fbd14d3f5b902203c091c0ec5b840a80be739d29b5fc2c75cb94928e5ea83133f84d226f28cd4b701"), + (hex"3045022100d8eaa436faec6b38f155065893f1212ce43615fbec49b4af72f16119774b5472022033aa303992f4a8cfe1c77e6a0d2baa73baad0305a88da16d26122e536867431101", hex"304402203af7b7ea16cc018fdb414f52cd38ed548dc257cbb06c812c9dc1d60500b21485022072cd74b7e49bfd813e09bae778da903b44b7b0ae22b87af4c34cf8bb77dfdef201"), + (hex"304402204f5dd042bfb449c522012a2d461e5a94c9ea3be629c0ab091b0e1f5569eb119c022021411ff8affabab12cd39f0eaa64f1b08fa72ada6f37d1d46c6bde4483d869fb01", hex"3044022043573edb37be815d1b97b90803f601dfc91c25279ccda606ad6515fee721fe57022030ac2883408a2075a47337443eb539062a8ac6b5453befb2b9863d697e35dd8201"), + (hex"3044022030ff3d4d42ef1c3d742164a30ff7b021215e881d9277a52a1720514a4473289502204b090f6b412e8caacb5bcbf295babb075d9d5490e3f7678c289206780f6f0bc901", hex"304502210093fd7dfa3ef6cdf5b94cfadf83022be98062d53cd7097a73947453b210a481eb0220622e63a21b787ea7bb55f01ab6fe503fcb8ef4cb65adce7a264ae014403646fe01") + ) + + val sigs = c.commitments + .localCommit + .publishableTxs + .htlcTxsAndSigs + .map(data => (Scripts.der(data.localSig), Scripts.der(data.remoteSig))) + + assert(ref === sigs) + } + + test("backward compatibility DATA_WAIT_FOR_FUNDING_CONFIRMED_COMPAT_01_Codec") { // this is a DATA_WAIT_FOR_FUNDING_CONFIRMED encoded with the previous version of the codec (at commit 997aceea82942769649bf03e95c5ea549a7beb0c) val bin_old = hex"000001033785fe882e8682340d11df42213f182755531bd587ae305e0062f563a52d841800049b86343ecd1baa49e0304a6e32dddeb50000000000000222000000012a05f2000000000000004e2000000000000000010090001e800bd48a66494d6275d73cc4b8e167bf840c9261a471271ec380000000c501c99c425578eb58841cbf2f7f2e435e796c654697b8076d4cedc90a7e1389589a0000000000000111000000009502f900000000000000271000000000000000008048000f01419f088c6cd366cadb656148952b730fdf73ccbcf030758c008e6a900f756bfb011fa7aae5886b9c34c5f264d996a7a1def7566424c0f90db8b688794b9ca43db8017331002fd85b09961fa68a1a6c2bc995e717ecf99f10c428a79457a46ce5d47b01325bcce8670aa8e0373c279531553ef280791c283189b1acdee55c21d239cdd90196e7a6fc79329b936e87a07b2d429e7b61ff89db92a4c66ec70e2562a14664570000000140410080000000000000000000000002ee000000003b9aca000000000000000000001278970eefbc9e9c7f44d0ab40555711618404aebd87d861ceca9867ce4f7bfe5d000000000015c0420f0000000000110010326963ce09728e7b80fd51c6d6b7f64d6e124cf55c0d2e887bc862499e325da00023a91081419f088c6cd366cadb656148952b730fdf73ccbcf030758c008e6a900f756bfb1081484d9633cfc4a9ab9f4220a7b3c679e648f18e53a7dadb7154242943b587415aa957009d81000000000080f8970eefbc9e9c7f44d0ab40555711618404aebd87d861ceca9867ce4f7bfe5d00000000007b7ef94000a1400f000000000011001013dc34f3aebaa16836581958168fcc55a5719f1a0c312ea9033c110afb4c677c82002418228110806fb9c53b82a46021cf2b48a18dc49434e9d207f3bff2f09c84e5df5f9526057481100c5bab065bd059dafb7ccef1ce14a850a4bb206b132b53cb9df70faa5be8812e00a39822011021c7d70a781a0ceb7605bed811e9aacdbff8c71f2904d54a7f57a46bd735c9f901101b6fde320e8cc9388538ab65bb2f55ac7cec1218163ec0d590e13ac3fbd7d60e80a3a91081419f088c6cd366cadb656148952b730fdf73ccbcf030758c008e6a900f756bfb1081484d9633cfc4a9ab9f4220a7b3c679e648f18e53a7dadb7154242943b587415aa95770612810000000000000000000000000000002ee0000000000000000000000003b9aca0030e78713eebb77ebfb57a70dee19a85a4e54a11fdf74c9fda7fc108ceaa942db8133978aafdb8e7232a61dca8495134873c1c9ceebb926c85256f432b73b111a9f00000000000000000000000000000000000000000000000000000000000040f5a7aef68b8bc802d20427a43145bfbeded7d322c363f661569a38c58064da6700093c4b8777de4f4e3fa26855a02aab88b0c202575ec3ec30e7654c33e727bdff2e80000000000ae0210780000000000880081934b1e704b9473dc07ea8e36b5bfb26b709267aae0697443de43124cf192ed00011d48840a0cf84463669b3656db2b0a44a95b987efb9e65e78183ac60047354807bab5fd8840a426cb19e7e254d5cfa11053d9e33cf32478c729d3ed6db8aa1214a1dac3a0ad54ab80001e25c3bbef27a71fd1342ad01555c45861012baf61f61873b2a619f393deff9740237cd8e4ea0093bb773bab03a938d5e35e9ebbb5b321ffd7ee031feff96eb82f8970eefbc9e9c7f44d0ab40555711618404aebd87d861ceca9867ce4f7bfe5d000006b0aade318a54c3339808654a781d421412758912d2df1b039399ffed52d3b784f698e9230da056f09212e8ac5cebe7ab1283c08aa3cd548ed5e1a4f81ebfe10" // currently version=0 and discriminator type=1 @@ -192,4 +238,137 @@ class ChannelCodecsSpec extends FunSuite { assert(data_new === data_new2) } + test("tell channel_update length") { + // with option_channel_htlc_max (136 bytes) + val u1 = hex"81D6DE1B150A0EAD83B214C879BD55FB3EE82E54F3F38DF601B692B481DFFBBF66582C018B271FBEBF17B0F72FAD1E1B78EF19232621AA2D8055B51D94C5A39543497FD7F826957108F4A30FD9CEC3AEBA79972084E90EAD01EA33090000000013AB9500006E00005D117A190100009000000000000003E8000003E80000000100000003E8000000".bits + // without option_channel_htlc_max (128 bytes) + val u2 = hex"A94A853FCDE515F89259E03D10368B1A600B3BF78F6BD5C968469C0816F45EFF7878714DF26B580D5A304334E46816D5AC37B098EBC46C1CE47E37504D052DD643497FD7F826957108F4A30FD9CEC3AEBA79972084E90EAD01EA33090000000013AB9500006E00005D1149290001009000000000000003E8000003E800000001".bits + + // check that we decode correct length, and that we just take a peek without actually consuming data + assert(noUnknownFieldsChannelUpdateSizeCodec.decode(u1) == Attempt.successful(DecodeResult(136, u1))) + assert(noUnknownFieldsChannelUpdateSizeCodec.decode(u2) == Attempt.successful(DecodeResult(128, u2))) + } + + test("backward compatibility DATA_NORMAL_COMPAT_03_Codec (roundtrip)") { + val oldbins = List( + hex"00000303af0ed6052cf28d670665549bc86f4b721c9fdb309d40c58f5811f63966e005d000010000002a000000000000022200000000000000320000000000002710000000000000c3500090003280000001b337b78001b130b90193d163e9dd3a94d6be66a6919dff41e3af5437e98ae8a50576cb25ecd213c3be00000000000001110000000000000019000000000000138800000000000061a800480019018dc262ab3d8932204cae9f6ad55d02b2eb8f0c1a30240cffce0bfaf4eaee83c78126a5b6689b0819654de9575cec805526a2ecf56c0564a119ba6228d392a683b301298ff303409a281e9391899913e433d647d3641e29bf4d2261e2dedee58ff19b81a313bcd6a5569ca8a30a3a8d38842f978870e3d2c9f2701877dadc390e72ad8581f80350c6ab29e276fa9c8ff91d30f81ffc1e91bf44077308c3fd4f9bcd0147050001b337b78001b130b900800000000000000000028000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b71b01922a9715e7ecc3ce2bdd1365f5bb21031ea449de9266835e03cf9cc53b28242c000007dc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e8480ccd0f55bf0c57aeed91f83171d3f1c40112e290addc467672054b23a1abe524a000003e8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d09009f4fb68f3e1dac82202f9aa581ce0bbf1f765df0e9ac3c8c57e20f685abab8ed000001f8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f42403966b742116203fdb684c348788985bef6bf617bfaf0e985ecea90f80a9b1bc9800000fa8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a1201d61deed074e4ed7ee11573983b363768007418c5925ac537e9fe25595bbb2928000007d800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017700000000000030d4000000000002ab9800092fbd9f938bee777bacd1865cf35318aaecd4142c6b75dca656e082d61292212240000000000ae025a6000000000008800817a7b675021fe0a85125af89ae10ba5a3e6b8b9978cc7f64fee5f87d7195de4d0011d48840c6e131559ec4991026574fb56aae815975c7860d1812067fe705fd7a757741e3c840ebf48a79768b3055b47ee4a708afda1e1e46b6b495d18538707977b35969c68dd4ab80028080000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005b8d80c9154b8af3f661e715ee89b2fadd90818f5224ef493341af01e7ce629d941216000003ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f424066687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925000001f4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e84804fa7db479f0ed6411017cd52c0e705df8fbb2ef874d61e462bf107b42d5d5c76800000fc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a1201cb35ba108b101fedb4261a43c44c2df7b5fb0bdfd7874c2f675487c054d8de4c000007d4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d0900eb0ef7683a7276bf708ab9cc1d9b1bb4003a0c62c92d629bf4ff12acaddd9494000003ec0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bb800000000000186a00000000000155cc00606060606060606060606060606060606060606060606060606060606060606068c4ef35a955a72a28c28ea34e210be5e21c38f4b27c9c061df6b70e439cab61600000000000000000000000000000000000000000000000000000000000400000000000000540002000000000000753000048484848484848484848484848484848484848484848484848484848484848484000000000000005600000000014fb1800000000001312d0102ffbfb9dfb84acd2c2e3100054402a6c713d9b5d9d0865c7723fc56c3ea26f9490024bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a48848900000000002b80969800000000002200205e9ed9d4087f82a14496be26b842e968f9ae2e65e331fd93fb97e1f5c657793400475221031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f2103afd229e5da2cc156d1fb929c22bf6878791adad2574614e1c1e5decd65a71a3752ae00000000000000000000000000000000000000000000000000000000000000000000000000000000001562095db1aa5fca1c46275348acc0f071419b58ebfb86f5fcb03882bcf441b528869a358d38c9e68ae24a37d198d6a022de4c8a70264cff735f47c6314f3e9e6482095db1aa5fca1c46275348acc0f071419b58ebfb86f5fcb03882bcf441b528869a358d38c9e68ae24a37d198d6a022de4c8a70264cff735f47c6314f3e9e6482095db1aa5fca1c46275348acc0f071419b58ebfb86f5fcb03882bcf441b528869a358d38c9e68ae24a37d198d6a022de4c8a70264cff735f47c6314f3e9e6482095db1aa5fca1c46275348acc0f071419b58ebfb86f5fcb03882bcf441b528869a358d38c9e68ae24a37d198d6a022de4c8a70264cff735f47c6314f3e9e6480000dfc518156de366e5834d448d5cc7ee9f263d06cbc2b41138d1ac320000000000000002000004000606a2e9ffc3c021237b3133e0084ad9fe3f03a39c8f97fb77a7fdab79d1979e7d3007fbb20f299bd8046d496629a8467f571378e55960302b1f42b71e2a5bdf44c34c079b41e9a6ddb5d42e218fb2a8cedbf2a730a0ecaea800f1a8319a94cc59be940a0434a3aeeaf6b2c02b9496df043026c7aca1865942915d15fba51c40ae196a6911294617c9ae1b6c5c076a183fa7fc371b3c5fc458fc99b2f5867cd5c4786c3a005cc1872cdd819fdb48b146b83ecd890797bfe09098635fa6b86aeeeb5ad395b8222222222222222222222222222222222222222222222222222222222222222200000000000459b2ba247fea00020054000000000000001e0000047e0000006b5c858d4a8c72ab8fa1f966ada74456261df6a8bb73867063c275254b297ff56b002af83f5a05bd93af024e990f60db85ff40e59b03548e5316f1647c2a72efe8d16cdc736211c124bd66ae4200", + hex"00000303af0ed6052cf28d670665549bc86f4b721c9fdb309d40c58f5811f63966e005d000010000002a000000000000022200000000000000320000000000002710000000000000c3500090003280000001b337b78001b130b90193d163e9dd3a94d6be66a6919dff41e3af5437e98ae8a50576cb25ecd213c3be00000000000001110000000000000019000000000000138800000000000061a800480019018dc262ab3d8932204cae9f6ad55d02b2eb8f0c1a30240cffce0bfaf4eaee83c78126a5b6689b0819654de9575cec805526a2ecf56c0564a119ba6228d392a683b301298ff303409a281e9391899913e433d647d3641e29bf4d2261e2dedee58ff19b81a313bcd6a5569ca8a30a3a8d38842f978870e3d2c9f2701877dadc390e72ad8581f80350c6ab29e276fa9c8ff91d30f81ffc1e91bf44077308c3fd4f9bcd0147050001b337b78001b130b900800000000000000000028000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b71b01922a9715e7ecc3ce2bdd1365f5bb21031ea449de9266835e03cf9cc53b28242c000007dc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e8480ccd0f55bf0c57aeed91f83171d3f1c40112e290addc467672054b23a1abe524a000003e8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d09009f4fb68f3e1dac82202f9aa581ce0bbf1f765df0e9ac3c8c57e20f685abab8ed000001f8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f42403966b742116203fdb684c348788985bef6bf617bfaf0e985ecea90f80a9b1bc9800000fa8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a1201d61deed074e4ed7ee11573983b363768007418c5925ac537e9fe25595bbb2928000007d800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017700000000000030d4000000000002ab9800092fbd9f938bee777bacd1865cf35318aaecd4142c6b75dca656e082d61292212240000000000ae025a6000000000008800817a7b675021fe0a85125af89ae10ba5a3e6b8b9978cc7f64fee5f87d7195de4d0011d48840c6e131559ec4991026574fb56aae815975c7860d1812067fe705fd7a757741e3c840ebf48a79768b3055b47ee4a708afda1e1e46b6b495d18538707977b35969c68dd4ab80028080000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005b8d80c9154b8af3f661e715ee89b2fadd90818f5224ef493341af01e7ce629d941216000003ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f424066687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925000001f4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e84804fa7db479f0ed6411017cd52c0e705df8fbb2ef874d61e462bf107b42d5d5c76800000fc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a1201cb35ba108b101fedb4261a43c44c2df7b5fb0bdfd7874c2f675487c054d8de4c000007d4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d0900eb0ef7683a7276bf708ab9cc1d9b1bb4003a0c62c92d629bf4ff12acaddd9494000003ec0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bb800000000000186a00000000000155cc00606060606060606060606060606060606060606060606060606060606060606068c4ef35a955a72a28c28ea34e210be5e21c38f4b27c9c061df6b70e439cab61600000000000000000000000000000000000000000000000000000000000400000000000000540002000000000000753000048484848484848484848484848484848484848484848484848484848484848484000000000000005600000000014fb1800000000001312d0102ffbfb9dfb84acd2c2e3100054402a6c713d9b5d9d0865c7723fc56c3ea26f9490024bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a48848900000000002b80969800000000002200205e9ed9d4087f82a14496be26b842e968f9ae2e65e331fd93fb97e1f5c657793400475221031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f2103afd229e5da2cc156d1fb929c22bf6878791adad2574614e1c1e5decd65a71a3752ae00000000000000000000000000000000000000000000000000000000000000000000000000000000001562095db1aa5fca1c46275348acc0f071419b58ebfb86f5fcb03882bcf441b528869a358d38c9e68ae24a37d198d6a022de4c8a70264cff735f47c6314f3e9e6482095db1aa5fca1c46275348acc0f071419b58ebfb86f5fcb03882bcf441b528869a358d38c9e68ae24a37d198d6a022de4c8a70264cff735f47c6314f3e9e6482095db1aa5fca1c46275348acc0f071419b58ebfb86f5fcb03882bcf441b528869a358d38c9e68ae24a37d198d6a022de4c8a70264cff735f47c6314f3e9e6482095db1aa5fca1c46275348acc0f071419b58ebfb86f5fcb03882bcf441b528869a358d38c9e68ae24a37d198d6a022de4c8a70264cff735f47c6314f3e9e6480000dfc518156de366e5834d448d5cc7ee9f263d06cbc2b41138d1ac320000000000000002000004000606a2e9ffc3c021237b3133e0084ad9fe3f03a39c8f97fb77a7fdab79d1979e7d3007fbb20f299bd8046d496629a8467f571378e55960302b1f42b71e2a5bdf44c34c079b41e9a6ddb5d42e218fb2a8cedbf2a730a0ecaea800f1a8319a94cc59be940a0434a3aeeaf6b2c02b9496df043026c7aca1865942915d15fba51c40ae196a6911294617c9ae1b6c5c076a183fa7fc371b3c5fc458fc99b2f5867cd5c4786c3a005cc1872cdd819fdb48b146b83ecd890797bfe09098635fa6b86aeeeb5ad395b8222222222222222222222222222222222222222222222222222222222222222200000000000459b2ba247fea00020054000000000000001e0000047e0000006b5c858d4a8c72ab8fa1f966ada74456261df6a8bb73867063c275254b297ff56b002af83f5a05bd93af024e990f60db85ff40e59b03548e5316f1647c2a72efe8d16cdc736211c124bd66ae4200", + hex"00000303af0ed6052cf28d670665549bc86f4b721c9fdb309d40c58f5811f63966e005d000010000002a000000000000022200000000000000320000000000002710000000000000c3500090003280000001b337b78001b130b90193d163e9dd3a94d6be66a6919dff41e3af5437e98ae8a50576cb25ecd213c3be00000000000001110000000000000019000000000000138800000000000061a800480019018dc262ab3d8932204cae9f6ad55d02b2eb8f0c1a30240cffce0bfaf4eaee83c78126a5b6689b0819654de9575cec805526a2ecf56c0564a119ba6228d392a683b301298ff303409a281e9391899913e433d647d3641e29bf4d2261e2dedee58ff19b81a313bcd6a5569ca8a30a3a8d38842f978870e3d2c9f2701877dadc390e72ad8581f80350c6ab29e276fa9c8ff91d30f81ffc1e91bf44077308c3fd4f9bcd0147050001b337b78001b130b900800000000000000000028000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b71b01922a9715e7ecc3ce2bdd1365f5bb21031ea449de9266835e03cf9cc53b28242c000007dc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e8480ccd0f55bf0c57aeed91f83171d3f1c40112e290addc467672054b23a1abe524a000003e8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d09009f4fb68f3e1dac82202f9aa581ce0bbf1f765df0e9ac3c8c57e20f685abab8ed000001f8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f42403966b742116203fdb684c348788985bef6bf617bfaf0e985ecea90f80a9b1bc9800000fa8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a1201d61deed074e4ed7ee11573983b363768007418c5925ac537e9fe25595bbb2928000007d800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017700000000000030d4000000000002ab9800092fbd9f938bee777bacd1865cf35318aaecd4142c6b75dca656e082d61292212240000000000ae025a6000000000008800817a7b675021fe0a85125af89ae10ba5a3e6b8b9978cc7f64fee5f87d7195de4d0011d48840c6e131559ec4991026574fb56aae815975c7860d1812067fe705fd7a757741e3c840ebf48a79768b3055b47ee4a708afda1e1e46b6b495d18538707977b35969c68dd4ab80028080000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005b8d80c9154b8af3f661e715ee89b2fadd90818f5224ef493341af01e7ce629d941216000003ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f424066687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925000001f4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e84804fa7db479f0ed6411017cd52c0e705df8fbb2ef874d61e462bf107b42d5d5c76800000fc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a1201cb35ba108b101fedb4261a43c44c2df7b5fb0bdfd7874c2f675487c054d8de4c000007d4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d0900eb0ef7683a7276bf708ab9cc1d9b1bb4003a0c62c92d629bf4ff12acaddd9494000003ec0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bb800000000000186a00000000000155cc00606060606060606060606060606060606060606060606060606060606060606068c4ef35a955a72a28c28ea34e210be5e21c38f4b27c9c061df6b70e439cab61600000000000000000000000000000000000000000000000000000000000400000000000000540002000000000000753000048484848484848484848484848484848484848484848484848484848484848484000000000000005600000000014fb1800000000001312d0102ffbfb9dfb84acd2c2e3100054402a6c713d9b5d9d0865c7723fc56c3ea26f9490024bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a48848900000000002b80969800000000002200205e9ed9d4087f82a14496be26b842e968f9ae2e65e331fd93fb97e1f5c657793400475221031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f2103afd229e5da2cc156d1fb929c22bf6878791adad2574614e1c1e5decd65a71a3752ae00000000000000000000000000000000000000000000000000000000000000000000000000000000001562095db1aa5fca1c46275348acc0f071419b58ebfb86f5fcb03882bcf441b528869a358d38c9e68ae24a37d198d6a022de4c8a70264cff735f47c6314f3e9e6482095db1aa5fca1c46275348acc0f071419b58ebfb86f5fcb03882bcf441b528869a358d38c9e68ae24a37d198d6a022de4c8a70264cff735f47c6314f3e9e6482095db1aa5fca1c46275348acc0f071419b58ebfb86f5fcb03882bcf441b528869a358d38c9e68ae24a37d198d6a022de4c8a70264cff735f47c6314f3e9e6482095db1aa5fca1c46275348acc0f071419b58ebfb86f5fcb03882bcf441b528869a358d38c9e68ae24a37d198d6a022de4c8a70264cff735f47c6314f3e9e6480000dfc518156de366e5834d448d5cc7ee9f263d06cbc2b41138d1ac320000000000000002000004000606a2e9ffc3c021237b3133e0084ad9fe3f03a39c8f97fb77a7fdab79d1979e7d3007fbb20f299bd8046d496629a8467f571378e55960302b1f42b71e2a5bdf44c34c079b41e9a6ddb5d42e218fb2a8cedbf2a730a0ecaea800f1a8319a94cc59be940a0434a3aeeaf6b2c02b9496df043026c7aca1865942915d15fba51c40ae196a6911294617c9ae1b6c5c076a183fa7fc371b3c5fc458fc99b2f5867cd5c4786c3a005cc1872cdd819fdb48b146b83ecd890797bfe09098635fa6b86aeeeb5ad395b8222222222222222222222222222222222222222222222222222222222222222200000000000459b2ba247fea00020054000000000000001e0000047e0000006bf331a269b4c7ed856111126f052529808bdecea1d402b5b0c701b52c97053888002a59ee5bd534c22b1e254c152940280b275fdc3fbeec89517e4b5b67b36b1865ede835ebd0dd00ab0c98ad8686c02716f8bb267949f42bf42752a63418f161308bc333dd3d5e9f2da7824500155cea941f3e0286759e6ae0b82c3f723c3b72849b4d5ddd9b9226f5f08344b64f49940b575b6b29bef53600", + hex"00000303af0ed6052cf28d670665549bc86f4b721c9fdb309d40c58f5811f63966e005d000010000002a000000000000022200000000000000320000000000002710000000000000c3500090003280000001b337b78001b130b90193d163e9dd3a94d6be66a6919dff41e3af5437e98ae8a50576cb25ecd213c3be00000000000001110000000000000019000000000000138800000000000061a800480019018dc262ab3d8932204cae9f6ad55d02b2eb8f0c1a30240cffce0bfaf4eaee83c78126a5b6689b0819654de9575cec805526a2ecf56c0564a119ba6228d392a683b301298ff303409a281e9391899913e433d647d3641e29bf4d2261e2dedee58ff19b81a313bcd6a5569ca8a30a3a8d38842f978870e3d2c9f2701877dadc390e72ad8581f80350c6ab29e276fa9c8ff91d30f81ffc1e91bf44077308c3fd4f9bcd0147050001b337b78001b130b900800000000000000000028000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b71b01922a9715e7ecc3ce2bdd1365f5bb21031ea449de9266835e03cf9cc53b28242c000007dc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e8480ccd0f55bf0c57aeed91f83171d3f1c40112e290addc467672054b23a1abe524a000003e8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d09009f4fb68f3e1dac82202f9aa581ce0bbf1f765df0e9ac3c8c57e20f685abab8ed000001f8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f42403966b742116203fdb684c348788985bef6bf617bfaf0e985ecea90f80a9b1bc9800000fa8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a1201d61deed074e4ed7ee11573983b363768007418c5925ac537e9fe25595bbb2928000007d800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017700000000000030d4000000000002ab9800092fbd9f938bee777bacd1865cf35318aaecd4142c6b75dca656e082d61292212240000000000ae025a6000000000008800817a7b675021fe0a85125af89ae10ba5a3e6b8b9978cc7f64fee5f87d7195de4d0011d48840c6e131559ec4991026574fb56aae815975c7860d1812067fe705fd7a757741e3c840ebf48a79768b3055b47ee4a708afda1e1e46b6b495d18538707977b35969c68dd4ab80028080000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005b8d80c9154b8af3f661e715ee89b2fadd90818f5224ef493341af01e7ce629d941216000003ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f424066687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925000001f4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e84804fa7db479f0ed6411017cd52c0e705df8fbb2ef874d61e462bf107b42d5d5c76800000fc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a1201cb35ba108b101fedb4261a43c44c2df7b5fb0bdfd7874c2f675487c054d8de4c000007d4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d0900eb0ef7683a7276bf708ab9cc1d9b1bb4003a0c62c92d629bf4ff12acaddd9494000003ec0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bb800000000000186a00000000000155cc00606060606060606060606060606060606060606060606060606060606060606068c4ef35a955a72a28c28ea34e210be5e21c38f4b27c9c061df6b70e439cab61600000000000000000000000000000000000000000000000000000000000400000000000000540002000000000000753000048484848484848484848484848484848484848484848484848484848484848484000000000000005600000000014fb1800000000001312d0102ffbfb9dfb84acd2c2e3100054402a6c713d9b5d9d0865c7723fc56c3ea26f9490024bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a48848900000000002b80969800000000002200205e9ed9d4087f82a14496be26b842e968f9ae2e65e331fd93fb97e1f5c657793400475221031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f2103afd229e5da2cc156d1fb929c22bf6878791adad2574614e1c1e5decd65a71a3752ae0000000000000000000000000000000000000000000000000000000000000000000000000000000000155294617c9ae1b6c5c076a183fa7fc371b3c5fc458fc99b2f5867cd5c4786c3a005cc1872cdd819fdb48b146b83ecd890797bfe09098635fa6b86aeeeb5ad395b8222222222222222222222222222222222222222222222222222222222222222200000000000459b2ba247fea00020054000000000000001e0000047e0000006b5e9de91a6478fe57a3e851222e8c7a3c88a2fed283901f4871ec9d9c269d1f88002a30ca18940020b43675f3383dff31c0838ad31f6ca9958b8df45da80da9962663773e71207a657d668bf2879b5c654b6bd869eed39f4186492199944bff7e5a93577b05cbfe634321514d80153c20910775551fbe8eb51bf91d2b1063b6e17b2d7a3b030483fcf1b5654e2afcfb381873739cba0a05ef00", + hex"00000303af0ed6052cf28d670665549bc86f4b721c9fdb309d40c58f5811f63966e005d000010000002a000000000000022200000000000000320000000000002710000000000000c3500090003280000001b337b78001b130b90193d163e9dd3a94d6be66a6919dff41e3af5437e98ae8a50576cb25ecd213c3be00000000000001110000000000000019000000000000138800000000000061a800480019018dc262ab3d8932204cae9f6ad55d02b2eb8f0c1a30240cffce0bfaf4eaee83c78126a5b6689b0819654de9575cec805526a2ecf56c0564a119ba6228d392a683b301298ff303409a281e9391899913e433d647d3641e29bf4d2261e2dedee58ff19b81a313bcd6a5569ca8a30a3a8d38842f978870e3d2c9f2701877dadc390e72ad8581f80350c6ab29e276fa9c8ff91d30f81ffc1e91bf44077308c3fd4f9bcd0147050001b337b78001b130b900800000000000000000028000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b71b01922a9715e7ecc3ce2bdd1365f5bb21031ea449de9266835e03cf9cc53b28242c000007dc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e8480ccd0f55bf0c57aeed91f83171d3f1c40112e290addc467672054b23a1abe524a000003e8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d09009f4fb68f3e1dac82202f9aa581ce0bbf1f765df0e9ac3c8c57e20f685abab8ed000001f8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f42403966b742116203fdb684c348788985bef6bf617bfaf0e985ecea90f80a9b1bc9800000fa8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a1201d61deed074e4ed7ee11573983b363768007418c5925ac537e9fe25595bbb2928000007d800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017700000000000030d4000000000002ab9800092fbd9f938bee777bacd1865cf35318aaecd4142c6b75dca656e082d61292212240000000000ae025a6000000000008800817a7b675021fe0a85125af89ae10ba5a3e6b8b9978cc7f64fee5f87d7195de4d0011d48840c6e131559ec4991026574fb56aae815975c7860d1812067fe705fd7a757741e3c840ebf48a79768b3055b47ee4a708afda1e1e46b6b495d18538707977b35969c68dd4ab80028080000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005b8d80c9154b8af3f661e715ee89b2fadd90818f5224ef493341af01e7ce629d941216000003ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f424066687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925000001f4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e84804fa7db479f0ed6411017cd52c0e705df8fbb2ef874d61e462bf107b42d5d5c76800000fc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a1201cb35ba108b101fedb4261a43c44c2df7b5fb0bdfd7874c2f675487c054d8de4c000007d4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d0900eb0ef7683a7276bf708ab9cc1d9b1bb4003a0c62c92d629bf4ff12acaddd9494000003ec0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bb800000000000186a00000000000155cc00606060606060606060606060606060606060606060606060606060606060606068c4ef35a955a72a28c28ea34e210be5e21c38f4b27c9c061df6b70e439cab61600000000000000000000000000000000000000000000000000000000000400000000000000540002000000000000753000048484848484848484848484848484848484848484848484848484848484848484000000000000005600000000014fb1800000000001312d0102ffbfb9dfb84acd2c2e3100054402a6c713d9b5d9d0865c7723fc56c3ea26f9490024bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a48848900000000002b80969800000000002200205e9ed9d4087f82a14496be26b842e968f9ae2e65e331fd93fb97e1f5c657793400475221031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f2103afd229e5da2cc156d1fb929c22bf6878791adad2574614e1c1e5decd65a71a3752ae0000000000000000000000000000000000000000000000000000000000000000000000000000000000155294617c9ae1b6c5c076a183fa7fc371b3c5fc458fc99b2f5867cd5c4786c3a005cc1872cdd819fdb48b146b83ecd890797bfe09098635fa6b86aeeeb5ad395b8222222222222222222222222222222222222222222222222222222222222222200000000000459b2ba247fea00020054000000000000001e0000047e0000006b6d8da39cd140e7426fa82af4eda7343a56702c8a515abd602c6ec71443ad95c2002ac447de9ce87da33ddc3d9bf55956749bf69c13395a51ec5b1971142f430b92e3b2723ef2dd2ab520709500", + hex"00000303af0ed6052cf28d670665549bc86f4b721c9fdb309d40c58f5811f63966e005d000010000002a00000000000002220000000002faf0800000000000002710000000000000271000900032800000016f5680015f7781a82cdc4f8f7f30aad446a7887d4cc0d3e1084dc9bdb5e8e5b0c8ca70f5bb462e000000000000011100000000002625a0000000000000138800000000000009c400480019018dc262ab3d8932204cae9f6ad55d02b2eb8f0c1a30240cffce0bfaf4eaee83c78126a5b6689b0819654de9575cec805526a2ecf56c0564a119ba6228d392a683b301298ff303409a281e9391899913e433d647d3641e29bf4d2261e2dedee58ff19b81a313bcd6a5569ca8a30a3a8d38842f978870e3d2c9f2701877dadc390e72ad8581f80350c6ab29e276fa9c8ff91d30f81ffc1e91bf44077308c3fd4f9bcd01470500016f5680015f778080000000000000000002c000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000f424027d3eda3cf876b20880be6a9607382efc7dd977c3a6b0f2315f883da16aeae3b4000007e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e00000000005b8d80c9154b8af3f661e715ee89b2fadd90818f5224ef493341af01e7ce629d941216000003ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000001e848072cd6e8422c407fb6d098690f1130b7ded7ec2f7f5e1d30bd9d521f015363793000001f5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f00000000000f42403ac3bdda0e9c9dafdc22ae730766c6ed000e8318b24b58a6fd3fc4ab2b776525000000fb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d090199a1eab7e18af5ddb23f062e3a7e3880225c5215bb88cece40a96474357ca494000007d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001770000000000bebc2000000000010b076000092fbd9f938bee777bacd1865cf35318aaecd4142c6b75dca656e082d61292212240000000000ae025a6000000000008800817a7b675021fe0a85125af89ae10ba5a3e6b8b9978cc7f64fee5f87d7195de4d0011d48840c6e131559ec4991026574fb56aae815975c7860d1812067fe705fd7a757741e3c840ebf48a79768b3055b47ee4a708afda1e1e46b6b495d18538707977b35969c68dd4ab80028080000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000003e00000000005b8d80c9154b8af3f661e715ee89b2fadd90818f5224ef493341af01e7ce629d941216000003ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000001e848072cd6e8422c407fb6d098690f1130b7ded7ec2f7f5e1d30bd9d521f015363793000001f5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000f00000000000f42403ac3bdda0e9c9dafdc22ae730766c6ed000e8318b24b58a6fd3fc4ab2b776525000000fb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000f424027d3eda3cf876b20880be6a9607382efc7dd977c3a6b0f2315f883da16aeae3b4000007e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e8480ccd0f55bf0c57aeed91f83171d3f1c40112e290addc467672054b23a1abe524a000003e80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bb800000000000186a00000000000155cc00606060606060606060606060606060606060606060606060606060606060606068c4ef35a955a72a28c28ea34e210be5e21c38f4b27c9c061df6b70e439cab616000000000000000000000000000000000000004000000000000000080004000000000000005400071170d49a0d7890596541859abfcacc78000000000000753000045454545454545454545454545454545454545454545454545454545454545454000000000000005600000000014fb1800000000001312d010232127dae95d9b2ebdb58e84cb369ac52f5f8378a57337bdb0883faa1dce1e40c0024bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a48848900000000002b80969800000000002200205e9ed9d4087f82a14496be26b842e968f9ae2e65e331fd93fb97e1f5c657793400475221031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f2103afd229e5da2cc156d1fb929c22bf6878791adad2574614e1c1e5decd65a71a3752ae0000000000000000000000000000000000000000000000000000000000000000000000000000000000154a91daf3412b0a03126494bcf38606251bcd2dc2fdeb61f29be3dc28faaefcfe0ec15070b07373460a1340146387ca1fb0ee5d0b2399f797bc8fa9b0d805fc358020202020202020202020202020202020202020202020202020202020202020200000000000459b2ba24846802000054000000000000001e0000047e0000006a00000007d000000000", + hex"00000303af0ed6052cf28d670665549bc86f4b721c9fdb309d40c58f5811f63966e005d000010000002a00000000000002220000000002faf0800000000000002710000000000000271000900032800000016f5680015f7781a82cdc4f8f7f30aad446a7887d4cc0d3e1084dc9bdb5e8e5b0c8ca70f5bb462e000000000000011100000000002625a0000000000000138800000000000009c400480019018dc262ab3d8932204cae9f6ad55d02b2eb8f0c1a30240cffce0bfaf4eaee83c78126a5b6689b0819654de9575cec805526a2ecf56c0564a119ba6228d392a683b301298ff303409a281e9391899913e433d647d3641e29bf4d2261e2dedee58ff19b81a313bcd6a5569ca8a30a3a8d38842f978870e3d2c9f2701877dadc390e72ad8581f80350c6ab29e276fa9c8ff91d30f81ffc1e91bf44077308c3fd4f9bcd01470500016f5680015f778080000000000000000002c000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000f424027d3eda3cf876b20880be6a9607382efc7dd977c3a6b0f2315f883da16aeae3b4000007e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e00000000005b8d80c9154b8af3f661e715ee89b2fadd90818f5224ef493341af01e7ce629d941216000003ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000001e848072cd6e8422c407fb6d098690f1130b7ded7ec2f7f5e1d30bd9d521f015363793000001f5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f00000000000f42403ac3bdda0e9c9dafdc22ae730766c6ed000e8318b24b58a6fd3fc4ab2b776525000000fb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d090199a1eab7e18af5ddb23f062e3a7e3880225c5215bb88cece40a96474357ca494000007d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001770000000000bebc2000000000010b076000092fbd9f938bee777bacd1865cf35318aaecd4142c6b75dca656e082d61292212240000000000ae025a6000000000008800817a7b675021fe0a85125af89ae10ba5a3e6b8b9978cc7f64fee5f87d7195de4d0011d48840c6e131559ec4991026574fb56aae815975c7860d1812067fe705fd7a757741e3c840ebf48a79768b3055b47ee4a708afda1e1e46b6b495d18538707977b35969c68dd4ab80028080000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000003e00000000005b8d80c9154b8af3f661e715ee89b2fadd90818f5224ef493341af01e7ce629d941216000003ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000001e848072cd6e8422c407fb6d098690f1130b7ded7ec2f7f5e1d30bd9d521f015363793000001f5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000f00000000000f42403ac3bdda0e9c9dafdc22ae730766c6ed000e8318b24b58a6fd3fc4ab2b776525000000fb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000f424027d3eda3cf876b20880be6a9607382efc7dd977c3a6b0f2315f883da16aeae3b4000007e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e8480ccd0f55bf0c57aeed91f83171d3f1c40112e290addc467672054b23a1abe524a000003e80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bb800000000000186a00000000000155cc00606060606060606060606060606060606060606060606060606060606060606068c4ef35a955a72a28c28ea34e210be5e21c38f4b27c9c061df6b70e439cab616000000000000000000000000000000000000004000000000000000080004000000000000005400071170d49a0d7890596541859abfcacc78000000000000753000045454545454545454545454545454545454545454545454545454545454545454000000000000005600000000014fb1800000000001312d010232127dae95d9b2ebdb58e84cb369ac52f5f8378a57337bdb0883faa1dce1e40c0024bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a48848900000000002b80969800000000002200205e9ed9d4087f82a14496be26b842e968f9ae2e65e331fd93fb97e1f5c657793400475221031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f2103afd229e5da2cc156d1fb929c22bf6878791adad2574614e1c1e5decd65a71a3752ae0000000000000000000000000000000000000000000000000000000000000000000000000000000000156f3e533754ca7b7780f42694dbe0cc8153864708e6bb0073c9b486a4d026a45d9142a46849870bfe07e92ac8a04968ecfef9d1eb137535603e893cefa1cbf7b64c59c33c4fbb17251ef48b7a3f62ad7ec06d47cf4e3856f2d2b3dde963340f5a0758cc599a4ecb882b77cf47700b00b9916910596dd20794db75e4eef2e6c9c60febcca5b484c9ec1608834c7c22b874f601b2f315066a3aea7ffa256eb94ba9a8d0b58c0e3ea3c74a2f6dcce6d0dd54a60375531f2efa98961332a8d442bf55b3ee244c21af045c81be8d380516436f1b3e1dd9797a2fe17932080f4e184c6338eae5c5058e9414ad0e523ab7a065a0948979f52e4c2839bc394ad706b429ad80000dfc518156de366e5834d448d5cc7ee9f263d06cbc2b41138d1ac320000000000000002000004000604507392d46705e690307786517fea3b9d30d23fa4abd3653f77134d1d0e3392a804f7b82122f515d8ccd2fff9598cba8836fbb7f46a2a8e31b5745c77d03c6b715a0492244be04f6aedcb750a6c70028807e725f44a305bd30b6535fbe62de8fe2382056b3de2cdc59ad67ad3b9689698b92f07809c6d50a241ca50bc586137e0708bbca91daf3412b0a03126494bcf38606251bcd2dc2fdeb61f29be3dc28faaefcfe0ec15070b07373460a1340146387ca1fb0ee5d0b2399f797bc8fa9b0d805fc358020202020202020202020202020202020202020202020202020202020202020200000000000459b2ba24846802000054000000000000001e0000047e0000006a00000007d000000000", + hex"00000303af0ed6052cf28d670665549bc86f4b721c9fdb309d40c58f5811f63966e005d000010000002a00000000000002220000000002faf0800000000000002710000000000000271000900032800000016f5680015f7781a82cdc4f8f7f30aad446a7887d4cc0d3e1084dc9bdb5e8e5b0c8ca70f5bb462e000000000000011100000000002625a0000000000000138800000000000009c400480019018dc262ab3d8932204cae9f6ad55d02b2eb8f0c1a30240cffce0bfaf4eaee83c78126a5b6689b0819654de9575cec805526a2ecf56c0564a119ba6228d392a683b301298ff303409a281e9391899913e433d647d3641e29bf4d2261e2dedee58ff19b81a313bcd6a5569ca8a30a3a8d38842f978870e3d2c9f2701877dadc390e72ad8581f80350c6ab29e276fa9c8ff91d30f81ffc1e91bf44077308c3fd4f9bcd01470500016f5680015f778080000000000000000002c000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000f424027d3eda3cf876b20880be6a9607382efc7dd977c3a6b0f2315f883da16aeae3b4000007e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e00000000005b8d80c9154b8af3f661e715ee89b2fadd90818f5224ef493341af01e7ce629d941216000003ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000001e848072cd6e8422c407fb6d098690f1130b7ded7ec2f7f5e1d30bd9d521f015363793000001f5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f00000000000f42403ac3bdda0e9c9dafdc22ae730766c6ed000e8318b24b58a6fd3fc4ab2b776525000000fb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d090199a1eab7e18af5ddb23f062e3a7e3880225c5215bb88cece40a96474357ca494000007d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001770000000000bebc2000000000010b076000092fbd9f938bee777bacd1865cf35318aaecd4142c6b75dca656e082d61292212240000000000ae025a6000000000008800817a7b675021fe0a85125af89ae10ba5a3e6b8b9978cc7f64fee5f87d7195de4d0011d48840c6e131559ec4991026574fb56aae815975c7860d1812067fe705fd7a757741e3c840ebf48a79768b3055b47ee4a708afda1e1e46b6b495d18538707977b35969c68dd4ab80028080000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000003e00000000005b8d80c9154b8af3f661e715ee89b2fadd90818f5224ef493341af01e7ce629d941216000003ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000001e848072cd6e8422c407fb6d098690f1130b7ded7ec2f7f5e1d30bd9d521f015363793000001f5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000f00000000000f42403ac3bdda0e9c9dafdc22ae730766c6ed000e8318b24b58a6fd3fc4ab2b776525000000fb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000f424027d3eda3cf876b20880be6a9607382efc7dd977c3a6b0f2315f883da16aeae3b4000007e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e8480ccd0f55bf0c57aeed91f83171d3f1c40112e290addc467672054b23a1abe524a000003e80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bb800000000000186a00000000000155cc00606060606060606060606060606060606060606060606060606060606060606068c4ef35a955a72a28c28ea34e210be5e21c38f4b27c9c061df6b70e439cab616000000000000000000000000000000000000004000000000000000080004000000000000005400071170d49a0d7890596541859abfcacc78000000000000753000045454545454545454545454545454545454545454545454545454545454545454000000000000005600000000014fb1800000000001312d010232127dae95d9b2ebdb58e84cb369ac52f5f8378a57337bdb0883faa1dce1e40c0024bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a48848900000000002b80969800000000002200205e9ed9d4087f82a14496be26b842e968f9ae2e65e331fd93fb97e1f5c657793400475221031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f2103afd229e5da2cc156d1fb929c22bf6878791adad2574614e1c1e5decd65a71a3752ae0000000000000000000000000000000000000000000000000000000000000000000000000000000000156f3e533754ca7b7780f42694dbe0cc8153864708e6bb0073c9b486a4d026a45d9142a46849870bfe07e92ac8a04968ecfef9d1eb137535603e893cefa1cbf7b64c59c33c4fbb17251ef48b7a3f62ad7ec06d47cf4e3856f2d2b3dde963340f5a0758cc599a4ecb882b77cf47700b00b9916910596dd20794db75e4eef2e6c9c60febcca5b484c9ec1608834c7c22b874f601b2f315066a3aea7ffa256eb94ba9a8d0b58c0e3ea3c74a2f6dcce6d0dd54a60375531f2efa98961332a8d442bf55b3ee244c21af045c81be8d380516436f1b3e1dd9797a2fe17932080f4e184c6338eae5c5058e9414ad0e523ab7a065a0948979f52e4c2839bc394ad706b429ad80000dfc518156de366e5834d448d5cc7ee9f263d06cbc2b41138d1ac320000000000000002000004000604507392d46705e690307786517fea3b9d30d23fa4abd3653f77134d1d0e3392a804f7b82122f515d8ccd2fff9598cba8836fbb7f46a2a8e31b5745c77d03c6b715a0492244be04f6aedcb750a6c70028807e725f44a305bd30b6535fbe62de8fe2382056b3de2cdc59ad67ad3b9689698b92f07809c6d50a241ca50bc586137e0708bbca91daf3412b0a03126494bcf38606251bcd2dc2fdeb61f29be3dc28faaefcfe0ec15070b07373460a1340146387ca1fb0ee5d0b2399f797bc8fa9b0d805fc358020202020202020202020202020202020202020202020202020202020202020200000000000459b2ba24846802000054000000000000001e0000047e0000006a00000007d0000001aa17af5812b244fdd14b29dfb4238f93d2841f471816fda220fc31213664cc23002abf4517129784b9f3d4f86591a38715dfda74f0c59abbd2b2999386494d55960717ac8e9d56635ad0b99700", + hex"00000303af0ed6052cf28d670665549bc86f4b721c9fdb309d40c58f5811f63966e005d000010000002a00000000000002220000000002faf0800000000000002710000000000000271000900032800000016f5680015f7781a82cdc4f8f7f30aad446a7887d4cc0d3e1084dc9bdb5e8e5b0c8ca70f5bb462e000000000000011100000000002625a0000000000000138800000000000009c400480019018dc262ab3d8932204cae9f6ad55d02b2eb8f0c1a30240cffce0bfaf4eaee83c78126a5b6689b0819654de9575cec805526a2ecf56c0564a119ba6228d392a683b301298ff303409a281e9391899913e433d647d3641e29bf4d2261e2dedee58ff19b81a313bcd6a5569ca8a30a3a8d38842f978870e3d2c9f2701877dadc390e72ad8581f80350c6ab29e276fa9c8ff91d30f81ffc1e91bf44077308c3fd4f9bcd01470500016f5680015f778080000000000000000002c000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000f424027d3eda3cf876b20880be6a9607382efc7dd977c3a6b0f2315f883da16aeae3b4000007e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e00000000005b8d80c9154b8af3f661e715ee89b2fadd90818f5224ef493341af01e7ce629d941216000003ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000001e848072cd6e8422c407fb6d098690f1130b7ded7ec2f7f5e1d30bd9d521f015363793000001f5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f00000000000f42403ac3bdda0e9c9dafdc22ae730766c6ed000e8318b24b58a6fd3fc4ab2b776525000000fb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d090199a1eab7e18af5ddb23f062e3a7e3880225c5215bb88cece40a96474357ca494000007d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001770000000000bebc2000000000010b076000092fbd9f938bee777bacd1865cf35318aaecd4142c6b75dca656e082d61292212240000000000ae025a6000000000008800817a7b675021fe0a85125af89ae10ba5a3e6b8b9978cc7f64fee5f87d7195de4d0011d48840c6e131559ec4991026574fb56aae815975c7860d1812067fe705fd7a757741e3c840ebf48a79768b3055b47ee4a708afda1e1e46b6b495d18538707977b35969c68dd4ab80028080000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000003e00000000005b8d80c9154b8af3f661e715ee89b2fadd90818f5224ef493341af01e7ce629d941216000003ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000001e848072cd6e8422c407fb6d098690f1130b7ded7ec2f7f5e1d30bd9d521f015363793000001f5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000f00000000000f42403ac3bdda0e9c9dafdc22ae730766c6ed000e8318b24b58a6fd3fc4ab2b776525000000fb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000f424027d3eda3cf876b20880be6a9607382efc7dd977c3a6b0f2315f883da16aeae3b4000007e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e8480ccd0f55bf0c57aeed91f83171d3f1c40112e290addc467672054b23a1abe524a000003e80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bb800000000000186a00000000000155cc00606060606060606060606060606060606060606060606060606060606060606068c4ef35a955a72a28c28ea34e210be5e21c38f4b27c9c061df6b70e439cab616000000000000000000000000000000000000004000000000000000080004000000000000005400071170d49a0d7890596541859abfcacc78000000000000753000045454545454545454545454545454545454545454545454545454545454545454000000000000005600000000014fb1800000000001312d010232127dae95d9b2ebdb58e84cb369ac52f5f8378a57337bdb0883faa1dce1e40c0024bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a48848900000000002b80969800000000002200205e9ed9d4087f82a14496be26b842e968f9ae2e65e331fd93fb97e1f5c657793400475221031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f2103afd229e5da2cc156d1fb929c22bf6878791adad2574614e1c1e5decd65a71a3752ae0000000000000000000000000000000000000000000000000000000000000000000000000000000000156f3e533754ca7b7780f42694dbe0cc8153864708e6bb0073c9b486a4d026a45d9142a46849870bfe07e92ac8a04968ecfef9d1eb137535603e893cefa1cbf7b64c59c33c4fbb17251ef48b7a3f62ad7ec06d47cf4e3856f2d2b3dde963340f5a0758cc599a4ecb882b77cf47700b00b9916910596dd20794db75e4eef2e6c9c60febcca5b484c9ec1608834c7c22b874f601b2f315066a3aea7ffa256eb94ba9a8d0b58c0e3ea3c74a2f6dcce6d0dd54a60375531f2efa98961332a8d442bf55b3ee244c21af045c81be8d380516436f1b3e1dd9797a2fe17932080f4e184c6338eae5c5058e9414ad0e523ab7a065a0948979f52e4c2839bc394ad706b429ad80000dfc518156de366e5834d448d5cc7ee9f263d06cbc2b41138d1ac320000000000000002000004000604507392d46705e690307786517fea3b9d30d23fa4abd3653f77134d1d0e3392a804f7b82122f515d8ccd2fff9598cba8836fbb7f46a2a8e31b5745c77d03c6b715a0492244be04f6aedcb750a6c70028807e725f44a305bd30b6535fbe62de8fe2382056b3de2cdc59ad67ad3b9689698b92f07809c6d50a241ca50bc586137e0708bbca91daf3412b0a03126494bcf38606251bcd2dc2fdeb61f29be3dc28faaefcfe0ec15070b07373460a1340146387ca1fb0ee5d0b2399f797bc8fa9b0d805fc358020202020202020202020202020202020202020202020202020202020202020200000000000459b2ba24846802000054000000000000001e0000047e0000006a00000007d000000141457ceb9407293dd4481318fd2da9c6f63c5dfb59fdc91b1793084b5b5effb3002aa5b677089a1263d5025f3fd1e57fa057ab13609b78e335d581ff56109aa40a3069373c1cab1f89066e139c3126090eea2396fb806c8f4ff3a52bff536b63c455805a678ac5b1a432d7d200157039a400d6f98feb6bcbdafa0345d58c2c1217a2d2c6a297ef2cd39532aaa1b3fcee6719042ff4a09d6f80", + hex"00000303af0ed6052cf28d670665549bc86f4b721c9fdb309d40c58f5811f63966e005d000010000002a00000000000002220000000002faf0800000000000002710000000000000271000900032800000016f5680015f7781a82cdc4f8f7f30aad446a7887d4cc0d3e1084dc9bdb5e8e5b0c8ca70f5bb462e000000000000011100000000002625a0000000000000138800000000000009c400480019018dc262ab3d8932204cae9f6ad55d02b2eb8f0c1a30240cffce0bfaf4eaee83c78126a5b6689b0819654de9575cec805526a2ecf56c0564a119ba6228d392a683b301298ff303409a281e9391899913e433d647d3641e29bf4d2261e2dedee58ff19b81a313bcd6a5569ca8a30a3a8d38842f978870e3d2c9f2701877dadc390e72ad8581f80350c6ab29e276fa9c8ff91d30f81ffc1e91bf44077308c3fd4f9bcd01470500016f5680015f778080000000000000000002c000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000f424027d3eda3cf876b20880be6a9607382efc7dd977c3a6b0f2315f883da16aeae3b4000007e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e00000000005b8d80c9154b8af3f661e715ee89b2fadd90818f5224ef493341af01e7ce629d941216000003ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000001e848072cd6e8422c407fb6d098690f1130b7ded7ec2f7f5e1d30bd9d521f015363793000001f5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f00000000000f42403ac3bdda0e9c9dafdc22ae730766c6ed000e8318b24b58a6fd3fc4ab2b776525000000fb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d090199a1eab7e18af5ddb23f062e3a7e3880225c5215bb88cece40a96474357ca494000007d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001770000000000bebc2000000000010b076000092fbd9f938bee777bacd1865cf35318aaecd4142c6b75dca656e082d61292212240000000000ae025a6000000000008800817a7b675021fe0a85125af89ae10ba5a3e6b8b9978cc7f64fee5f87d7195de4d0011d48840c6e131559ec4991026574fb56aae815975c7860d1812067fe705fd7a757741e3c840ebf48a79768b3055b47ee4a708afda1e1e46b6b495d18538707977b35969c68dd4ab80028080000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000003e00000000005b8d80c9154b8af3f661e715ee89b2fadd90818f5224ef493341af01e7ce629d941216000003ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000001e848072cd6e8422c407fb6d098690f1130b7ded7ec2f7f5e1d30bd9d521f015363793000001f5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000f00000000000f42403ac3bdda0e9c9dafdc22ae730766c6ed000e8318b24b58a6fd3fc4ab2b776525000000fb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000f424027d3eda3cf876b20880be6a9607382efc7dd977c3a6b0f2315f883da16aeae3b4000007e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e8480ccd0f55bf0c57aeed91f83171d3f1c40112e290addc467672054b23a1abe524a000003e80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bb800000000000186a00000000000155cc00606060606060606060606060606060606060606060606060606060606060606068c4ef35a955a72a28c28ea34e210be5e21c38f4b27c9c061df6b70e439cab616000000000000000000000000000000000000004000000000000000080004000000000000005400071170d49a0d7890596541859abfcacc78000000000000753000045454545454545454545454545454545454545454545454545454545454545454000000000000005600000000014fb1800000000001312d010232127dae95d9b2ebdb58e84cb369ac52f5f8378a57337bdb0883faa1dce1e40c0024bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a48848900000000002b80969800000000002200205e9ed9d4087f82a14496be26b842e968f9ae2e65e331fd93fb97e1f5c657793400475221031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f2103afd229e5da2cc156d1fb929c22bf6878791adad2574614e1c1e5decd65a71a3752ae0000000000000000000000000000000000000000000000000000000000000000000000000000000000154a91daf3412b0a03126494bcf38606251bcd2dc2fdeb61f29be3dc28faaefcfe0ec15070b07373460a1340146387ca1fb0ee5d0b2399f797bc8fa9b0d805fc358020202020202020202020202020202020202020202020202020202020202020200000000000459b2ba24846802000054000000000000001e0000047e0000006a00000007d0000001dc1f2ab0cd4b19c58ea0261604ecfb938cc72a0c175808c996d0493bb7b9b279002a87ddd6eba29744cdf4e6cf63ddfff74a99de823dfc99ddd9a4407b47beeee6b0e045c968610b0f58dfb9c41e2f2ccc916abc8ad3e91857024b8554c2e6df2fc1904d859431c83afeed7a001549ddac755c583fe55b54cf24f4400fca26a97fd59a1e6f8686bf4f57d37f3e84ac63bc9dd05dc95a47c680", + hex"00000303af0ed6052cf28d670665549bc86f4b721c9fdb309d40c58f5811f63966e005d000010000002a00000000000002220000000002faf0800000000000002710000000000000271000900032800000016f5680015f7781a82cdc4f8f7f30aad446a7887d4cc0d3e1084dc9bdb5e8e5b0c8ca70f5bb462e000000000000011100000000002625a0000000000000138800000000000009c400480019018dc262ab3d8932204cae9f6ad55d02b2eb8f0c1a30240cffce0bfaf4eaee83c78126a5b6689b0819654de9575cec805526a2ecf56c0564a119ba6228d392a683b301298ff303409a281e9391899913e433d647d3641e29bf4d2261e2dedee58ff19b81a313bcd6a5569ca8a30a3a8d38842f978870e3d2c9f2701877dadc390e72ad8581f80350c6ab29e276fa9c8ff91d30f81ffc1e91bf44077308c3fd4f9bcd01470500016f5680015f778080000000000000000002c000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000f424027d3eda3cf876b20880be6a9607382efc7dd977c3a6b0f2315f883da16aeae3b4000007e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e00000000005b8d80c9154b8af3f661e715ee89b2fadd90818f5224ef493341af01e7ce629d941216000003ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000001e848072cd6e8422c407fb6d098690f1130b7ded7ec2f7f5e1d30bd9d521f015363793000001f5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f00000000000f42403ac3bdda0e9c9dafdc22ae730766c6ed000e8318b24b58a6fd3fc4ab2b776525000000fb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d090199a1eab7e18af5ddb23f062e3a7e3880225c5215bb88cece40a96474357ca494000007d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001770000000000bebc2000000000010b076000092fbd9f938bee777bacd1865cf35318aaecd4142c6b75dca656e082d61292212240000000000ae025a6000000000008800817a7b675021fe0a85125af89ae10ba5a3e6b8b9978cc7f64fee5f87d7195de4d0011d48840c6e131559ec4991026574fb56aae815975c7860d1812067fe705fd7a757741e3c840ebf48a79768b3055b47ee4a708afda1e1e46b6b495d18538707977b35969c68dd4ab80028080000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000003e00000000005b8d80c9154b8af3f661e715ee89b2fadd90818f5224ef493341af01e7ce629d941216000003ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000001e848072cd6e8422c407fb6d098690f1130b7ded7ec2f7f5e1d30bd9d521f015363793000001f5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000f00000000000f42403ac3bdda0e9c9dafdc22ae730766c6ed000e8318b24b58a6fd3fc4ab2b776525000000fb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000f424027d3eda3cf876b20880be6a9607382efc7dd977c3a6b0f2315f883da16aeae3b4000007e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e8480ccd0f55bf0c57aeed91f83171d3f1c40112e290addc467672054b23a1abe524a000003e80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bb800000000000186a00000000000155cc00606060606060606060606060606060606060606060606060606060606060606068c4ef35a955a72a28c28ea34e210be5e21c38f4b27c9c061df6b70e439cab616000000000000000000000000000000000000004000000000000000080004000000000000005400071170d49a0d7890596541859abfcacc78000000000000753000045454545454545454545454545454545454545454545454545454545454545454000000000000005600000000014fb1800000000001312d010232127dae95d9b2ebdb58e84cb369ac52f5f8378a57337bdb0883faa1dce1e40c0024bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a48848900000000002b80969800000000002200205e9ed9d4087f82a14496be26b842e968f9ae2e65e331fd93fb97e1f5c657793400475221031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f2103afd229e5da2cc156d1fb929c22bf6878791adad2574614e1c1e5decd65a71a3752ae0000000000000000000000000000000000000000000000000000000000000000000000000000000000154a91daf3412b0a03126494bcf38606251bcd2dc2fdeb61f29be3dc28faaefcfe0ec15070b07373460a1340146387ca1fb0ee5d0b2399f797bc8fa9b0d805fc358020202020202020202020202020202020202020202020202020202020202020200000000000459b2ba24846802000054000000000000001e0000047e0000006a00000007d0000001d35f1ca511bbad8975f358be806cf64b8651b6253ae63c754648e3b4cc70840b002a6730634b8cd9abc89b932f79c1f6d04cda4bb2de8941d2f2f749e1e4cfb7dc451eb93177af8082b9224500", + hex"00000303933884AAF1D6B108397E5EFE5C86BCF2D8CA8D2F700EDA99DB9214FC2712B134000456E4167E3C0EB8C856C79CA31C97C0AA0000000000000222000000012A05F2000000000000028F5C000000000000000102D0001E000BD48A2402E80B723C42EE3E42938866EC6686ABB7ABF64380000000C501A7F2974C5074E9E10DBB3F0D9B8C40932EC63ABC610FAD7EB6B21C6D081A459B000000000000011E80000001EEFFFE5C00000000000147AE00000000000001F403F000F18146779F781067ED04B4957E14F1C5623AB653039B2B1D49910240848E4E682DB20131AD64F76FAF90CD7DE26892F1BDAB82FB9E02EF6538D82FF4204B5348F02AE081A5388E9474769D69C4F60A763AE0CCDB5228A06281DE64408871A927297FDFD8818B6383985ABD4F0AC22E73791CF3A4D63C592FA2648242D34B8334B1539E823381BB1F1404C37D9C2318F5FC6B1BF7ECF5E6835B779E3BE09BADCF6DF1F51DCFBC80000000C0808000000000000EFD80000000007F00000000061A0A4880000001EDE5F3C3801203B9C79160B5123CADE575E370480B57B0C816EB35DD7B27372EDA858622EB1E808000000015FFFFFF800000000011001029DFB814F6502A68D6F83B6049E3D2948A2080084083750626532FDB437169C20023A9108146779F781067ED04B4957E14F1C5623AB653039B2B1D49910240848E4E682DB21081B30694071254D8B3B9537320C014B8CB1052E5514F5EFC19CF2EB806308D5CF1A95700AD0100000000008083B9C79160B5123CADE575E370480B57B0C816EB35DD7B27372EDA858622EB1E80800000001961B4C001618F8180000000001100102E648BA30998A28C02C2DFD9DDCD0E0BA064DA199C55186485AFAB296B94E704426FFE00000000000B000A67D9B9FAADB91650E0146B1F742E5C16006708890200239822011026A6925C659D006FEB42D639F1E42DD13224EE49AA34E71B612CF96DB66A8CD4011032C22F653C54CC5E41098227427650644266D80DED45B7387AE0FFC10E529C4680A418228110807CB47D9C1A14CB832FB361C398EA672C9542F34A90BAD4288FA6AC5FC9E9845C01101CF71CAE9252D389135D8C606225DCF1E0333CCDF1FAE84B74FC5D3D440C25F880A3A9108146779F781067ED04B4957E14F1C5623AB653039B2B1D49910240848E4E682DB21081B30694071254D8B3B9537320C014B8CB1052E5514F5EFC19CF2EB806308D5CF1A9573D7C531000000000000000000F3180000000007F00000001EDE5F3C380000000061A0A48D64CA627B243AD5915A2E5D0BAD026762028DDF3304992B83A26D6C11735FC5F01ED56D769BDE7F6A068AF1A4BCFDF950321F3A4744B01B1DDC7498677F112AE1A80000000000000000000000000000000000000658000000000000819800040D37301C10C9419287E9A3B704EB6D7F45CC145DD77DCE8A63B0A47C8AB67467D800901DCE3C8B05A891E56F2BAF1B82405ABD8640B759AEEBD939B976D42C311758F40400000000AFFFFFFC00000000008800814EFDC0A7B2815346B7C1DB024F1E94A451040042041BA83132997EDA1B8B4E10011D48840A33BCFBC0833F6825A4ABF0A78E2B11D5B2981CD958EA4C881204247273416D90840D9834A03892A6C59DCA9B990600A5C65882972A8A7AF7E0CE7975C031846AE78D4AB8002000EC0003FFFFFFFF86801076D98A575A4CDFD0E3F44D1BB3CD3BBAF3BD04C38FED439ED90D88DF932A9296801A80007FFFFFFFF4008136A9D5896669E8724C5120FB6B36C241EF3CEF68AE0316161F04A9EE3EAFF36000FC0003FFFFFFFF86780106E4B5CC4155733A2427082907338051A5DA1E7CA6432840A5528ECAFFA3FB628801B80007FFFFFFFF10020CA4E125E9126107745D4354D4187ABCDE323117857A1DCEB7CCF60B2AAFA80C6003A0000FFFFFFFFE1C0080981575FD981A73A848CC0243CB467BF451F6811DAF4D71CAD8CE8B1E96DB190C01000003FFFFFFFF867400814C747E0FD8290BE8A3B8B3F73015A261479A71780CD3A0A9270234E4B394409C00D80003FFFFFFFF90020E1B9C9B10A97F15F5E1BB27FC8AC670DF8DADEAE4EDFAFB23BDD0AC705FDF51600340000FFFFFFFFF0020AD2581F3494A17B0BE3F63516D53F028A204FD3156D8B21AA4E57A8738D2062080007FFFFFFFF0CE83B9C79160B5123CADE575E370480B57B0C816EB35DD7B27372EDA858622EB1E0B8C1E00000B8000FA46CC2C7E9AB4A37C64216CD65C944E6D73998419D1A1AD2827AB6BC85B32280230764E374064EC82A3751E789607E23BEAE93FB0EDDD5E7FA803767079662E80EAEF384E2AFCB68049D9DC246119E77BD2ED4112330760CAB6CD3671CFCE006C584B9C95E0B554261E00154D40806EA694F44751B328A9291BAD124EFD5664280936EC92D27B242737E7E3E83B4704BA367B7DA5108F2F6EDFB1C38EE721A369E77EED71B12090BAEAAAC322C1457E31AB0C4DE5D9351943F10FD747742616A1AABD09F680B37D4105A8872695EE9B97FAB8985FAA9D747D45046229BF265CEEB300A40FE23040C5F335E0515496C58EE47418B72331FCC6F47A31A9B33B8E000008692FFAFF04D2AE211E9461FB39D875D74F32E4109D21D5A03D46612000000002E307800002E0002069FCA5D3141D3A78436ECFC366E31024CBB18EAF1843EB5FADAC871B42069166C0726710955E3AD621072FCBDFCB90D79E5B1951A5EE01DB533B72429F84E2562680519DE7DE0419FB412D255F853C71588EAD94C0E6CAC7526440902123939A0B6C806CC1A501C495362CEE54DCC830052E32C414B95453D7BF0673CBAE018C23573C69C694A8F88483050257A7366B838489731E5776B6FA0F02573401176D3E7FAEEF11E95A671420586631255F51A0EC2CF4D4D9F69D587712070FE1FB9316B71868692FFAFF04D2AE211E9461FB39D875D74F32E4109D21D5A03D46612000000002E307800002E0002BA11BBBA0202012000000000000007D0000007D0000000C800000007CFFFF83000", + hex"00000303933884AAF1D6B108397E5EFE5C86BCF2D8CA8D2F700EDA99DB9214FC2712B1340004D443ECE9D9C43A11A19B554BAAA6AD150000000000000222000000003B9ACA0000000000000249F000000000000000010090001E800BD48A22F4C80A42CC8BB29A764DBAEFC95674931FBE9A4380000000C50134D4A745996002F219B5FDBA1E045374DF589ECA06ABE23CECAE47343E65EDCF800000000000011E80000001BA90824000000000000124F800000000000001F4038500F1810AE1AF8A1D6F56F80855E26705F191BB07CD4E2434BC5BB1698E7E5880E2266201E8BFEEEEED725775B8116F6F82CF8E87835A5B45B184E56F272AD70D6078118601E06212B8C8F2E25B73EE7974FDCDF007E389B437BBFE238CCC3F3BF7121B6C5E81AA8589D21E9584B24A11F3ABBA5DAD48D121DD63C57A69CD767119C05DA159CB81A649D8CC0E136EB8DFBD2268B69DCA86F8CE4A604235A03D9D37AE7B07FC563F80000000C080800000000000271C000000000177000000002808B14600000001970039BA00123767F0F4F00D5E9FDF24177EF2872343D9F8FAEC65D3048BA575E70E00A0AB08800000000015E070F20000000000110010584241B5FB364208F6E64A80D1166DAD866186B10C015ED0283FF1C308C2105A0023A910810AE1AF8A1D6F56F80855E26705F191BB07CD4E2434BC5BB1698E7E5880E226621081DE8ADFA110DC8A94D8B9E9EF616BAE8598287C8F82AFDF0FC068697D570266FDA95700AD81000000000080B767F0F4F00D5E9FDF24177EF2872343D9F8FAEC65D3048BA575E70E00A0AB0880000000003E7AEDC0011ABE8A00000000001100101A9CE4B6AEF469590BC7BCC51DCEEAE9C86084055A63CC01E443C733FBE400B9B5B16800000000000B000A5E5700106D1A7097E4DE87EBAF1F8F2773842FA482002418228110805E84989A81F51ABD9D11889AE43E68FAD93659DEC019F1B8C0ADBF15A57B118B81101DCC1256F9306439AD3962C043FC47A5179CAAA001CCB23342BE0E8D92E4022780A4182281108074F306DA3751B84EC5FFB155BDCA7B8E02208BBDBC8D4F3327ABA557BF27CD1701102EF4AC8CC92F469DA9642D4D4162BC545F8B34ADE15B7D6F99808AA22B086B0180A3A910810AE1AF8A1D6F56F80855E26705F191BB07CD4E2434BC5BB1698E7E5880E226621081DE8ADFA110DC8A94D8B9E9EF616BAE8598287C8F82AFDF0FC068697D570266FDA9576F8099900000000000000000271C00000000017700000001970039BA000000002808B14648CE00AE97051EE10A3C361263F81A98165CE4AA7BA076933D4266E533585F24815C15DEACF0691332B38ECF23EC39982C5C978C748374A01BA9B30D501EE4F26E8000000000000000000000000000000000001224000000000000004B800040A911C460F1467952E3B99BED072F81BFB4454FF389636DCB399FE6A78113C28580091BB3F87A7806AF4FEF920BBF794391A1ECFC7D7632E98245D2BAF3870050558440000000000AF0387900000000000880082C2120DAFD9B21047B732540688B36D6C330C3588600AF68141FF8E18461082D0011D488408570D7C50EB7AB7C042AF13382F8C8DD83E6A7121A5E2DD8B4C73F2C407113310840EF456FD0886E454A6C5CF4F7B0B5D742CC143E47C157EF87E03434BEAB81337ED4AB8001C00F40003FFFFFFFEC7200403248A1D44DFA3AC9EC237D452C936400CAA86E9517CCCF2A8F77B7493CD70B6A00780001FFFFFFFF63A0041826829646B907A97FBD1455EA8673A12B8E7AA6EA790F7802E955CE3B69DE57E006E0001FFFFFFFF640081E51EB1F91218821E680B50E4B22DF8B094385BD33ACAE36BFC9E8C2F5AD2DA5400EC0003FFFFFFFEC7801047C26AD5435658D063EBCF73A5D0EEFE73ED6B73426246E8DFB3A21D1C4C7465001900007FFFFFFFE0040B115AC58BAAA900195893EA3B2AB408D2AD348AD047E3B6CB15E599625E38608006A0001FFFFFFFF7002033C39A21A38BB61F6FB33623771A9356D8885B7C12C939C770C939EF826286C200360000FFFFFFFFB4008104EF4271064A0973B053727C3E67352D00E25CAEED944F50782449CEAE8F50960001FFFFFFFF6390DD9FC3D3C0357A7F7C905DFBCA1C8D0F67E3EBB1974C122E95D79C380282AC222B21FA0007920001295AA1FB77029F7620A90EF7AE6A6CD31E4588B93264A7ADB76152D535C52E90B9E1B7C2376DABA316A6290F1A9730D4E5E44D0B1CB0EE6A795702E6A6BCDFCDA1A4BFEBFC134AB8847A5187ECE761D75D3CCB904274875680F51984800000000AC87E8001E480002E884D2A8080804800000000000001F4000001F40000003200000001BF08EB000" + ) + + oldbins.foreach { oldbin => + // check that this data has been encoded with the old 0x03 codec + assert(oldbin.startsWith(hex"000003")) + // we decode with compat codec + val oldnormal = stateDataCodec.decode(oldbin.bits).require.value + // and we encode with new codec + val newbin = stateDataCodec.encode(oldnormal).require.bytes + // make sure that encoding used the new 0x10 codec + assert(newbin.startsWith(hex"000010")) + // make sure that roundtrip yields the same data + val newnormal = stateDataCodec.decode(newbin.bits).require.value + assert(newnormal === oldnormal) + } + } + + test("backward compatibility DATA_NORMAL_COMPAT_03_Codec (integrity)") { + // this test makes sure that we actually produce the same objects than previous versions of eclair + + val refs = Map( + hex"00000303933884AAF1D6B108397E5EFE5C86BCF2D8CA8D2F700EDA99DB9214FC2712B134000456E4167E3C0EB8C856C79CA31C97C0AA0000000000000222000000012A05F2000000000000028F5C000000000000000102D0001E000BD48A2402E80B723C42EE3E42938866EC6686ABB7ABF64380000000C501A7F2974C5074E9E10DBB3F0D9B8C40932EC63ABC610FAD7EB6B21C6D081A459B000000000000011E80000001EEFFFE5C00000000000147AE00000000000001F403F000F18146779F781067ED04B4957E14F1C5623AB653039B2B1D49910240848E4E682DB20131AD64F76FAF90CD7DE26892F1BDAB82FB9E02EF6538D82FF4204B5348F02AE081A5388E9474769D69C4F60A763AE0CCDB5228A06281DE64408871A927297FDFD8818B6383985ABD4F0AC22E73791CF3A4D63C592FA2648242D34B8334B1539E823381BB1F1404C37D9C2318F5FC6B1BF7ECF5E6835B779E3BE09BADCF6DF1F51DCFBC80000000C0808000000000000EFD80000000007F00000000061A0A4880000001EDE5F3C3801203B9C79160B5123CADE575E370480B57B0C816EB35DD7B27372EDA858622EB1E808000000015FFFFFF800000000011001029DFB814F6502A68D6F83B6049E3D2948A2080084083750626532FDB437169C20023A9108146779F781067ED04B4957E14F1C5623AB653039B2B1D49910240848E4E682DB21081B30694071254D8B3B9537320C014B8CB1052E5514F5EFC19CF2EB806308D5CF1A95700AD0100000000008083B9C79160B5123CADE575E370480B57B0C816EB35DD7B27372EDA858622EB1E80800000001961B4C001618F8180000000001100102E648BA30998A28C02C2DFD9DDCD0E0BA064DA199C55186485AFAB296B94E704426FFE00000000000B000A67D9B9FAADB91650E0146B1F742E5C16006708890200239822011026A6925C659D006FEB42D639F1E42DD13224EE49AA34E71B612CF96DB66A8CD4011032C22F653C54CC5E41098227427650644266D80DED45B7387AE0FFC10E529C4680A418228110807CB47D9C1A14CB832FB361C398EA672C9542F34A90BAD4288FA6AC5FC9E9845C01101CF71CAE9252D389135D8C606225DCF1E0333CCDF1FAE84B74FC5D3D440C25F880A3A9108146779F781067ED04B4957E14F1C5623AB653039B2B1D49910240848E4E682DB21081B30694071254D8B3B9537320C014B8CB1052E5514F5EFC19CF2EB806308D5CF1A9573D7C531000000000000000000F3180000000007F00000001EDE5F3C380000000061A0A48D64CA627B243AD5915A2E5D0BAD026762028DDF3304992B83A26D6C11735FC5F01ED56D769BDE7F6A068AF1A4BCFDF950321F3A4744B01B1DDC7498677F112AE1A80000000000000000000000000000000000000658000000000000819800040D37301C10C9419287E9A3B704EB6D7F45CC145DD77DCE8A63B0A47C8AB67467D800901DCE3C8B05A891E56F2BAF1B82405ABD8640B759AEEBD939B976D42C311758F40400000000AFFFFFFC00000000008800814EFDC0A7B2815346B7C1DB024F1E94A451040042041BA83132997EDA1B8B4E10011D48840A33BCFBC0833F6825A4ABF0A78E2B11D5B2981CD958EA4C881204247273416D90840D9834A03892A6C59DCA9B990600A5C65882972A8A7AF7E0CE7975C031846AE78D4AB8002000EC0003FFFFFFFF86801076D98A575A4CDFD0E3F44D1BB3CD3BBAF3BD04C38FED439ED90D88DF932A9296801A80007FFFFFFFF4008136A9D5896669E8724C5120FB6B36C241EF3CEF68AE0316161F04A9EE3EAFF36000FC0003FFFFFFFF86780106E4B5CC4155733A2427082907338051A5DA1E7CA6432840A5528ECAFFA3FB628801B80007FFFFFFFF10020CA4E125E9126107745D4354D4187ABCDE323117857A1DCEB7CCF60B2AAFA80C6003A0000FFFFFFFFE1C0080981575FD981A73A848CC0243CB467BF451F6811DAF4D71CAD8CE8B1E96DB190C01000003FFFFFFFF867400814C747E0FD8290BE8A3B8B3F73015A261479A71780CD3A0A9270234E4B394409C00D80003FFFFFFFF90020E1B9C9B10A97F15F5E1BB27FC8AC670DF8DADEAE4EDFAFB23BDD0AC705FDF51600340000FFFFFFFFF0020AD2581F3494A17B0BE3F63516D53F028A204FD3156D8B21AA4E57A8738D2062080007FFFFFFFF0CE83B9C79160B5123CADE575E370480B57B0C816EB35DD7B27372EDA858622EB1E0B8C1E00000B8000FA46CC2C7E9AB4A37C64216CD65C944E6D73998419D1A1AD2827AB6BC85B32280230764E374064EC82A3751E789607E23BEAE93FB0EDDD5E7FA803767079662E80EAEF384E2AFCB68049D9DC246119E77BD2ED4112330760CAB6CD3671CFCE006C584B9C95E0B554261E00154D40806EA694F44751B328A9291BAD124EFD5664280936EC92D27B242737E7E3E83B4704BA367B7DA5108F2F6EDFB1C38EE721A369E77EED71B12090BAEAAAC322C1457E31AB0C4DE5D9351943F10FD747742616A1AABD09F680B37D4105A8872695EE9B97FAB8985FAA9D747D45046229BF265CEEB300A40FE23040C5F335E0515496C58EE47418B72331FCC6F47A31A9B33B8E000008692FFAFF04D2AE211E9461FB39D875D74F32E4109D21D5A03D46612000000002E307800002E0002069FCA5D3141D3A78436ECFC366E31024CBB18EAF1843EB5FADAC871B42069166C0726710955E3AD621072FCBDFCB90D79E5B1951A5EE01DB533B72429F84E2562680519DE7DE0419FB412D255F853C71588EAD94C0E6CAC7526440902123939A0B6C806CC1A501C495362CEE54DCC830052E32C414B95453D7BF0673CBAE018C23573C69C694A8F88483050257A7366B838489731E5776B6FA0F02573401176D3E7FAEEF11E95A671420586631255F51A0EC2CF4D4D9F69D587712070FE1FB9316B71868692FFAFF04D2AE211E9461FB39D875D74F32E4109D21D5A03D46612000000002E307800002E0002BA11BBBA0202012000000000000007D0000007D0000000C800000007CFFFF83000" -> """{"commitments":{"localParams":{"nodeId":"03933884aaf1d6b108397e5efe5c86bcf2d8ca8d2f700eda99db9214fc2712b134","channelKeyPath":{"path":[1457788542,1007597768,1455922339,479707306]},"dustLimitSatoshis":546,"maxHtlcValueInFlightMsat":5000000000,"channelReserveSatoshis":167772,"htlcMinimumMsat":1,"toSelfDelay":720,"maxAcceptedHtlcs":30,"isFunder":false,"defaultFinalScriptPubKey":"a9144805d016e47885dc7c852710cdd8cd0d576f57ec87","globalFeatures":"","localFeatures":"8a"},"remoteParams":{"nodeId":"034fe52e98a0e9d3c21b767e1b371881265d8c7578c21f5afd6d6438da10348b36","dustLimitSatoshis":573,"maxHtlcValueInFlightMsat":16609443000,"channelReserveSatoshis":167772,"htlcMinimumMsat":1000,"toSelfDelay":2016,"maxAcceptedHtlcs":483,"fundingPubKey":"028cef3ef020cfda09692afc29e38ac4756ca60736563a93220481091c9cd05b64","revocationBasepoint":"02635ac9eedf5f219afbc4d125e37b5705f73c05deca71b05fe84096a691e055c1","paymentBasepoint":"034a711d28e8ed3ad389ec14ec75c199b6a45140c503bcc88110e3524e52ffbfb1","delayedPaymentBasepoint":"0316c70730b57a9e15845ce6f239e749ac78b25f44c90485a697066962a73d0467","htlcBasepoint":"03763e280986fb384631ebf8d637efd9ebcd06b6ef3c77c1375b9edbe3ea3b9f79","globalFeatures":"","localFeatures":"81"},"channelFlags":1,"localCommit":{"index":7675,"spec":{"htlcs":[],"feeratePerKw":254,"toLocalMsat":204739729,"toRemoteMsat":16572475271},"publishableTxs":{"commitTx":{"txid":"e25a866b79212015e01e155e530fb547abc8276869f8740a9948e52ca231f1e4","tx":"0200000000010107738f22c16a24795bcaebc6e09016af61902dd66bbaf64e6e5db50b0c45d63d010000000032c3698002c31f0300000000002200205cc91746133145180585bfb3bb9a1c1740c9b43338aa30c90b5f5652d729ce0884dffc0000000000160014cfb373f55b722ca1c028d63ee85cb82c00ce1112040047304402204d4d24b8cb3a00dfd685ac73e3c85ba26449dc935469ce36c259f2db6cd519a8022065845eca78a998bc8213044e84eca0c884cdb01bda8b6e70f5c1ff821ca5388d01483045022100f968fb38342997065f66c38731d4ce592a85e6952175a8511f4d58bf93d308b8022039ee395d24a5a71226bb18c0c44bb9e3c066799be3f5d096e9f8ba7a88184bf101475221028cef3ef020cfda09692afc29e38ac4756ca60736563a93220481091c9cd05b642103660d280e24a9b16772a6e6418029719620a5caa29ebdf8339e5d700c611ab9e352ae7af8a620"},"htlcTxsAndSigs":[]}},"remoteCommit":{"index":7779,"spec":{"htlcs":[],"feeratePerKw":254,"toLocalMsat":16572475271,"toRemoteMsat":204739729},"txid":"ac994c4f64875ab22b45cba175a04cec4051bbe660932570744dad822e6bf8be","remotePerCommitmentPoint":"03daadaed37bcfed40d15e34979fbf2a0643e748e8960363bb8e930cefe2255c35"},"localChanges":{"proposed":[],"signed":[],"acked":[]},"remoteChanges":{"proposed":[],"acked":[],"signed":[]},"localNextHtlcId":203,"remoteNextHtlcId":4147,"originChannels":{},"remoteNextCommitInfo":"034dcc0704325064a1fa68edc13adb5fd173051775df73a298ec291f22ad9d19f6","commitInput":{"outPoint":"3dd6450c0bb55d6e4ef6ba6bd62d9061af1690e0c6ebca5b79246ac1228f7307:1","amountSatoshis":16777215},"remotePerCommitmentSecrets":null,"channelId":"07738f22c16a24795bcaebc6e09016af61902dd66bbaf64e6e5db50b0c45d63c"},"shortChannelId":"1513532x23x1","buried":true,"channelAnnouncement":{"nodeSignature1":"d2366163f4d5a51be3210b66b2e4a2736b9ccc20ce8d0d69413d5b5e42d991401183b271ba032764151ba8f3c4b03f11df5749fd876eeaf3fd401bb383cb3174","nodeSignature2":"075779c27157e5b4024ecee12308cf3bde976a0891983b0655b669b38e7e700362c25ce4af05aaa130f000aa6a04037534a7a23a8d99454948dd689277eab321","bitcoinSignature1":"4049b7649693d92139bf3f1f41da3825d1b3dbed2884797b76fd8e1c77390d1b4f3bf76b8d890485d7555619160a2bf18d58626f2ec9a8ca1f887eba3ba130b5","bitcoinSignature2":"0d55e84fb4059bea082d443934af74dcbfd5c4c2fd54eba3ea2823114df932e7759805207f1182062f99af028aa4b62c7723a0c5b9198fe637a3d18d4d99dc70","features":"","chainHash":"43497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea330900000000","shortChannelId":"1513532x23x1","nodeId1":"034fe52e98a0e9d3c21b767e1b371881265d8c7578c21f5afd6d6438da10348b36","nodeId2":"03933884aaf1d6b108397e5efe5c86bcf2d8ca8d2f700eda99db9214fc2712b134","bitcoinKey1":"028cef3ef020cfda09692afc29e38ac4756ca60736563a93220481091c9cd05b64","bitcoinKey2":"03660d280e24a9b16772a6e6418029719620a5caa29ebdf8339e5d700c611ab9e3"},"channelUpdate":{"signature":"4e34a547c424182812bd39b35c1c244b98f2bbb5b7d07812b9a008bb69f3fd77788f4ad338a102c331892afa8d076167a6a6cfb4eac3b890387f0fdc98b5b8c3","chainHash":"43497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea330900000000","shortChannelId":"1513532x23x1","timestamp":1560862173,"messageFlags":1,"channelFlags":1,"cltvExpiryDelta":144,"htlcMinimumMsat":1000,"feeBaseMsat":1000,"feeProportionalMillionths":100,"htlcMaximumMsat":16777215000}}""", + hex"00000303933884AAF1D6B108397E5EFE5C86BCF2D8CA8D2F700EDA99DB9214FC2712B1340004D443ECE9D9C43A11A19B554BAAA6AD150000000000000222000000003B9ACA0000000000000249F000000000000000010090001E800BD48A22F4C80A42CC8BB29A764DBAEFC95674931FBE9A4380000000C50134D4A745996002F219B5FDBA1E045374DF589ECA06ABE23CECAE47343E65EDCF800000000000011E80000001BA90824000000000000124F800000000000001F4038500F1810AE1AF8A1D6F56F80855E26705F191BB07CD4E2434BC5BB1698E7E5880E2266201E8BFEEEEED725775B8116F6F82CF8E87835A5B45B184E56F272AD70D6078118601E06212B8C8F2E25B73EE7974FDCDF007E389B437BBFE238CCC3F3BF7121B6C5E81AA8589D21E9584B24A11F3ABBA5DAD48D121DD63C57A69CD767119C05DA159CB81A649D8CC0E136EB8DFBD2268B69DCA86F8CE4A604235A03D9D37AE7B07FC563F80000000C080800000000000271C000000000177000000002808B14600000001970039BA00123767F0F4F00D5E9FDF24177EF2872343D9F8FAEC65D3048BA575E70E00A0AB08800000000015E070F20000000000110010584241B5FB364208F6E64A80D1166DAD866186B10C015ED0283FF1C308C2105A0023A910810AE1AF8A1D6F56F80855E26705F191BB07CD4E2434BC5BB1698E7E5880E226621081DE8ADFA110DC8A94D8B9E9EF616BAE8598287C8F82AFDF0FC068697D570266FDA95700AD81000000000080B767F0F4F00D5E9FDF24177EF2872343D9F8FAEC65D3048BA575E70E00A0AB0880000000003E7AEDC0011ABE8A00000000001100101A9CE4B6AEF469590BC7BCC51DCEEAE9C86084055A63CC01E443C733FBE400B9B5B16800000000000B000A5E5700106D1A7097E4DE87EBAF1F8F2773842FA482002418228110805E84989A81F51ABD9D11889AE43E68FAD93659DEC019F1B8C0ADBF15A57B118B81101DCC1256F9306439AD3962C043FC47A5179CAAA001CCB23342BE0E8D92E4022780A4182281108074F306DA3751B84EC5FFB155BDCA7B8E02208BBDBC8D4F3327ABA557BF27CD1701102EF4AC8CC92F469DA9642D4D4162BC545F8B34ADE15B7D6F99808AA22B086B0180A3A910810AE1AF8A1D6F56F80855E26705F191BB07CD4E2434BC5BB1698E7E5880E226621081DE8ADFA110DC8A94D8B9E9EF616BAE8598287C8F82AFDF0FC068697D570266FDA9576F8099900000000000000000271C00000000017700000001970039BA000000002808B14648CE00AE97051EE10A3C361263F81A98165CE4AA7BA076933D4266E533585F24815C15DEACF0691332B38ECF23EC39982C5C978C748374A01BA9B30D501EE4F26E8000000000000000000000000000000000001224000000000000004B800040A911C460F1467952E3B99BED072F81BFB4454FF389636DCB399FE6A78113C28580091BB3F87A7806AF4FEF920BBF794391A1ECFC7D7632E98245D2BAF3870050558440000000000AF0387900000000000880082C2120DAFD9B21047B732540688B36D6C330C3588600AF68141FF8E18461082D0011D488408570D7C50EB7AB7C042AF13382F8C8DD83E6A7121A5E2DD8B4C73F2C407113310840EF456FD0886E454A6C5CF4F7B0B5D742CC143E47C157EF87E03434BEAB81337ED4AB8001C00F40003FFFFFFFEC7200403248A1D44DFA3AC9EC237D452C936400CAA86E9517CCCF2A8F77B7493CD70B6A00780001FFFFFFFF63A0041826829646B907A97FBD1455EA8673A12B8E7AA6EA790F7802E955CE3B69DE57E006E0001FFFFFFFF640081E51EB1F91218821E680B50E4B22DF8B094385BD33ACAE36BFC9E8C2F5AD2DA5400EC0003FFFFFFFEC7801047C26AD5435658D063EBCF73A5D0EEFE73ED6B73426246E8DFB3A21D1C4C7465001900007FFFFFFFE0040B115AC58BAAA900195893EA3B2AB408D2AD348AD047E3B6CB15E599625E38608006A0001FFFFFFFF7002033C39A21A38BB61F6FB33623771A9356D8885B7C12C939C770C939EF826286C200360000FFFFFFFFB4008104EF4271064A0973B053727C3E67352D00E25CAEED944F50782449CEAE8F50960001FFFFFFFF6390DD9FC3D3C0357A7F7C905DFBCA1C8D0F67E3EBB1974C122E95D79C380282AC222B21FA0007920001295AA1FB77029F7620A90EF7AE6A6CD31E4588B93264A7ADB76152D535C52E90B9E1B7C2376DABA316A6290F1A9730D4E5E44D0B1CB0EE6A795702E6A6BCDFCDA1A4BFEBFC134AB8847A5187ECE761D75D3CCB904274875680F51984800000000AC87E8001E480002E884D2A8080804800000000000001F4000001F40000003200000001BF08EB000" -> """{"commitments":{"localParams":{"nodeId":"03933884aaf1d6b108397e5efe5c86bcf2d8ca8d2f700eda99db9214fc2712b134","channelKeyPath":{"path":[3561221353,3653515793,2711311691,2863050005]},"dustLimitSatoshis":546,"maxHtlcValueInFlightMsat":1000000000,"channelReserveSatoshis":150000,"htlcMinimumMsat":1,"toSelfDelay":144,"maxAcceptedHtlcs":30,"isFunder":true,"defaultFinalScriptPubKey":"a91445e990148599176534ec9b75df92ace9263f7d3487","globalFeatures":"","localFeatures":"8a"},"remoteParams":{"nodeId":"0269a94e8b32c005e4336bfb743c08a6e9beb13d940d57c479d95c8e687ccbdb9f","dustLimitSatoshis":573,"maxHtlcValueInFlightMsat":14850000000,"channelReserveSatoshis":150000,"htlcMinimumMsat":1000,"toSelfDelay":1802,"maxAcceptedHtlcs":483,"fundingPubKey":"0215c35f143adeadf010abc4ce0be323760f9a9c486978b762d31cfcb101c44cc4","revocationBasepoint":"03d17fdddddae4aeeb7022dedf059f1d0f06b4b68b6309cade4e55ae1ac0f0230c","paymentBasepoint":"03c0c4257191e5c4b6e7dcf2e9fb9be00fc713686f77fc4719987e77ee2436d8bd","delayedPaymentBasepoint":"03550b13a43d2b09649423e75774bb5a91a243bac78af4d39aece23380bb42b397","htlcBasepoint":"034c93b1981c26dd71bf7a44d16d3b950df19c94c0846b407b3a6f5cf60ff8ac7f","globalFeatures":"","localFeatures":"81"},"channelFlags":1,"localCommit":{"index":20024,"spec":{"htlcs":[],"feeratePerKw":750,"toLocalMsat":1343316620,"toRemoteMsat":13656683380},"publishableTxs":{"commitTx":{"txid":"65fe0b1f079fa763448df3ab8d94b1ad7d377c061121376be90b9c0c1bb0cd43","tx":"020000000001016ecfe1e9e01abd3fbe482efde50e4687b3f1f5d8cba609174aebce1c0141561100000000007cf5db8002357d1400000000002200203539c96d5de8d2b2178f798a3b9dd5d390c1080ab4c79803c8878e67f7c801736b62d00000000000160014bcae0020da34e12fc9bd0fd75e3f1e4ee7085f490400483045022100bd09313503ea357b3a231135c87cd1f5b26cb3bd8033e371815b7e2b4af6231702203b9824adf260c8735a72c58087f88f4a2f39554003996466857c1d1b25c8044f01483045022100e9e60db46ea3709d8bff62ab7b94f71c0441177b791a9e664f574aaf7e4f9a2e02205de95919925e8d3b52c85a9a82c578a8bf16695bc2b6fadf330115445610d603014752210215c35f143adeadf010abc4ce0be323760f9a9c486978b762d31cfcb101c44cc42103bd15bf4221b91529b173d3dec2d75d0b3050f91f055fbe1f80d0d2faae04cdfb52aedf013320"},"htlcTxsAndSigs":[]}},"remoteCommit":{"index":20024,"spec":{"htlcs":[],"feeratePerKw":750,"toLocalMsat":13656683380,"toRemoteMsat":1343316620},"txid":"919c015d2e0a3dc214786c24c7f035302cb9c954f740ed267a84cdca66b0be49","remotePerCommitmentPoint":"02b82bbd59e0d22665671d9e47d8733058b92f18e906e9403753661aa03dc9e4dd"},"localChanges":{"proposed":[],"signed":[],"acked":[]},"remoteChanges":{"proposed":[],"acked":[],"signed":[]},"localNextHtlcId":9288,"remoteNextHtlcId":151,"originChannels":{},"remoteNextCommitInfo":"02a4471183c519e54b8ee66fb41cbe06fed1153fce258db72ce67f9a9e044f0a16","commitInput":{"outPoint":"115641011cceeb4a1709a6cbd8f5f1b387460ee5fd2e48be3fbd1ae0e9e1cf6e:0","amountSatoshis":15000000},"remotePerCommitmentSecrets":null,"channelId":"6ecfe1e9e01abd3fbe482efde50e4687b3f1f5d8cba609174aebce1c01415611"},"shortChannelId":"1413373x969x0","buried":true,"channelUpdate":{"signature":"52b543f6ee053eec41521def5cd4d9a63c8b117264c94f5b6ec2a5aa6b8a5d2173c36f846edb57462d4c521e352e61a9cbc89a163961dcd4f2ae05cd4d79bf9b","chainHash":"43497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea330900000000","shortChannelId":"1413373x969x0","timestamp":1561369173,"messageFlags":1,"channelFlags":1,"cltvExpiryDelta":144,"htlcMinimumMsat":1000,"feeBaseMsat":1000,"feeProportionalMillionths":100,"htlcMaximumMsat":15000000000}}""" + ) + + refs.foreach { case (oldbin, refjson) => + // we decode with compat codec + val oldnormal = stateDataCodec.decode(oldbin.bits).require.value + // we then encode with new codec + val newbin = stateDataCodec.encode(oldnormal).require.bytes + // and we decode with the new codec + val newnormal = stateDataCodec.decode(newbin.bits).require.value + // finally we check that the actual data is the same as before (we just remove the new json field) + val oldjson = Serialization.write(oldnormal)(JsonSupport.formats).replace(""","unknownFields":""""", "") + val newjson = Serialization.write(newnormal)(JsonSupport.formats).replace(""","unknownFields":""""", "") + assert(oldjson === refjson) + assert(newjson === refjson) + } + + } + +} + +object ChannelCodecsSpec { + val keyManager = new LocalKeyManager(ByteVector32(ByteVector.fill(32)(1)), Block.RegtestGenesisBlock.hash) + val localParams = LocalParams( + keyManager.nodeId, + channelKeyPath = DeterministicWallet.KeyPath(Seq(42L)), + dustLimitSatoshis = Satoshi(546).toLong, + maxHtlcValueInFlightMsat = UInt64(50000000), + channelReserveSatoshis = 10000, + htlcMinimumMsat = 10000, + toSelfDelay = 144, + maxAcceptedHtlcs = 50, + defaultFinalScriptPubKey = ByteVector.empty, + isFunder = true, + globalFeatures = hex"dead", + localFeatures = hex"beef") + + val remoteParams = RemoteParams( + nodeId = randomKey.publicKey, + dustLimitSatoshis = Satoshi(546).toLong, + maxHtlcValueInFlightMsat = UInt64(5000000), + channelReserveSatoshis = 10000, + htlcMinimumMsat = 5000, + toSelfDelay = 144, + maxAcceptedHtlcs = 50, + fundingPubKey = PrivateKey(ByteVector32(ByteVector.fill(32)(1)) :+ 1.toByte).publicKey, + revocationBasepoint = PrivateKey(ByteVector.fill(32)(2)).publicKey, + paymentBasepoint = PrivateKey(ByteVector.fill(32)(3)).publicKey, + delayedPaymentBasepoint = PrivateKey(ByteVector.fill(32)(4)).publicKey, + htlcBasepoint = PrivateKey(ByteVector.fill(32)(6)).publicKey, + globalFeatures = hex"dead", + localFeatures = hex"beef") + + val paymentPreimages = Seq( + ByteVector32(hex"0000000000000000000000000000000000000000000000000000000000000000"), + ByteVector32(hex"0101010101010101010101010101010101010101010101010101010101010101"), + ByteVector32(hex"0202020202020202020202020202020202020202020202020202020202020202"), + ByteVector32(hex"0303030303030303030303030303030303030303030303030303030303030303"), + ByteVector32(hex"0404040404040404040404040404040404040404040404040404040404040404") + ) + + val htlcs = Seq( + DirectedHtlc(IN, UpdateAddHtlc(ByteVector32.Zeroes, 0, MilliSatoshi(1000000).amount, Crypto.sha256(paymentPreimages(0)), 500, ByteVector.fill(Sphinx.PacketLength)(0))), + DirectedHtlc(IN, UpdateAddHtlc(ByteVector32.Zeroes, 1, MilliSatoshi(2000000).amount, Crypto.sha256(paymentPreimages(1)), 501, ByteVector.fill(Sphinx.PacketLength)(0))), + DirectedHtlc(OUT, UpdateAddHtlc(ByteVector32.Zeroes, 30, MilliSatoshi(2000000).amount, Crypto.sha256(paymentPreimages(2)), 502, ByteVector.fill(Sphinx.PacketLength)(0))), + DirectedHtlc(OUT, UpdateAddHtlc(ByteVector32.Zeroes, 31, MilliSatoshi(3000000).amount, Crypto.sha256(paymentPreimages(3)), 503, ByteVector.fill(Sphinx.PacketLength)(0))), + DirectedHtlc(IN, UpdateAddHtlc(ByteVector32.Zeroes, 2, MilliSatoshi(4000000).amount, Crypto.sha256(paymentPreimages(4)), 504, ByteVector.fill(Sphinx.PacketLength)(0))) + ) + + val fundingTx = Transaction.read("0200000001adbb20ea41a8423ea937e76e8151636bf6093b70eaff942930d20576600521fd000000006b48304502210090587b6201e166ad6af0227d3036a9454223d49a1f11839c1a362184340ef0240220577f7cd5cca78719405cbf1de7414ac027f0239ef6e214c90fcaab0454d84b3b012103535b32d5eb0a6ed0982a0479bbadc9868d9836f6ba94dd5a63be16d875069184ffffffff028096980000000000220020c015c4a6be010e21657068fc2e6a9d02b27ebe4d490a25846f7237f104d1a3cd20256d29010000001600143ca33c2e4446f4a305f23c80df8ad1afdcf652f900000000") + val fundingAmount = fundingTx.txOut(0).amount + val commitmentInput = Funding.makeFundingInputInfo(fundingTx.hash, 0, fundingAmount, keyManager.fundingPublicKey(localParams.channelKeyPath).publicKey, remoteParams.fundingPubKey) + + val localCommit = LocalCommit(0, CommitmentSpec(htlcs.toSet, 1500, 50000000, 70000000), PublishableTxs(CommitTx(commitmentInput, Transaction(2, Nil, Nil, 0)), Nil)) + val remoteCommit = RemoteCommit(0, CommitmentSpec(htlcs.map(htlc => htlc.copy(direction = htlc.direction.opposite)).toSet, 1500, 50000, 700000), ByteVector32(hex"0303030303030303030303030303030303030303030303030303030303030303"), PrivateKey(ByteVector.fill(32)(4)).publicKey) + val commitments = Commitments(localParams, remoteParams, channelFlags = 0x01.toByte, localCommit, remoteCommit, LocalChanges(Nil, Nil, Nil), RemoteChanges(Nil, Nil, Nil), + localNextHtlcId = 32L, + remoteNextHtlcId = 4L, + originChannels = Map(42L -> Local(UUID.randomUUID, None), 15000L -> Relayed(ByteVector32(ByteVector.fill(32)(42)), 43, 11000000L, 10000000L)), + remoteNextCommitInfo = Right(randomKey.publicKey), + commitInput = commitmentInput, remotePerCommitmentSecrets = ShaChain.init, channelId = ByteVector32.Zeroes) + + val channelUpdate = Announcements.makeChannelUpdate(ByteVector32(ByteVector.fill(32)(1)), randomKey, randomKey.publicKey, ShortChannelId(142553), 42, 15, 575, 53, Channel.MAX_FUNDING_SATOSHIS * 1000L) + + val normal = DATA_NORMAL(commitments, ShortChannelId(42), true, None, channelUpdate, None, None) } From 7d89dd01a143ba70ac38db6578f68e217a545dc5 Mon Sep 17 00:00:00 2001 From: Fabrice Drouin Date: Tue, 9 Jul 2019 16:00:18 +0200 Subject: [PATCH 11/12] Electrum: update checkpoints (#1067) Checkpoints generated on July 9th 2019 --- .../electrum/checkpoints_mainnet.json | 1153 +++--- .../electrum/checkpoints_testnet.json | 3105 +++++++++-------- 2 files changed, 2290 insertions(+), 1968 deletions(-) diff --git a/eclair-core/src/main/resources/electrum/checkpoints_mainnet.json b/eclair-core/src/main/resources/electrum/checkpoints_mainnet.json index 3f1371605e..a8d15da278 100644 --- a/eclair-core/src/main/resources/electrum/checkpoints_mainnet.json +++ b/eclair-core/src/main/resources/electrum/checkpoints_mainnet.json @@ -1,1082 +1,1155 @@ [ [ - "00000000693067b0e6b440bc51450b9f3850561b07f6d3c021c54fbd6abb9763", + "00000000693067b0e6b440bc51450b9f3850561b07f6d3c021c54fbd6abb9763", 26959535291011309493156476344723991336010898738574164086137773096960 - ], + ], [ - "00000000f037ad09d0b05ee66b8c1da83030abaf909d2b1bf519c3c7d2cd3fdf", + "00000000f037ad09d0b05ee66b8c1da83030abaf909d2b1bf519c3c7d2cd3fdf", 26959535291011309493156476344723991336010898738574164086137773096960 - ], + ], [ - "000000006ce8b5f16fcedde13acbc9641baa1c67734f177d770a4069c06c9de8", + "000000006ce8b5f16fcedde13acbc9641baa1c67734f177d770a4069c06c9de8", 26959535291011309493156476344723991336010898738574164086137773096960 - ], + ], [ - "00000000563298de120522b5ae17da21aaae02eee2d7fcb5be65d9224dbd601c", + "00000000563298de120522b5ae17da21aaae02eee2d7fcb5be65d9224dbd601c", 26959535291011309493156476344723991336010898738574164086137773096960 - ], + ], [ - "000000009b0a4b2833b4a0aa61171ee75b8eb301ac45a18713795a72e461a946", + "000000009b0a4b2833b4a0aa61171ee75b8eb301ac45a18713795a72e461a946", 26959535291011309493156476344723991336010898738574164086137773096960 - ], + ], [ - "00000000fa8a7363e8f6fdc88ec55edf264c9c7b31268c26e497a4587c750584", + "00000000fa8a7363e8f6fdc88ec55edf264c9c7b31268c26e497a4587c750584", 26959535291011309493156476344723991336010898738574164086137773096960 - ], + ], [ - "000000008ac55b5cd76a5c176f2457f0e9df5ff1c719d939f1022712b1ba2092", + "000000008ac55b5cd76a5c176f2457f0e9df5ff1c719d939f1022712b1ba2092", 26959535291011309493156476344723991336010898738574164086137773096960 - ], + ], [ - "000000007f0c796631f00f542c0b402d638d3518bc208f8c9e5d29d2f169c084", + "000000007f0c796631f00f542c0b402d638d3518bc208f8c9e5d29d2f169c084", 26959535291011309493156476344723991336010898738574164086137773096960 - ], + ], [ - "00000000ffb062296c9d4eb5f87bbf905d30669d26eab6bced341bd3f1dba5fd", + "00000000ffb062296c9d4eb5f87bbf905d30669d26eab6bced341bd3f1dba5fd", 26959535291011309493156476344723991336010898738574164086137773096960 - ], + ], [ - "0000000074c108842c3ec2252bba62db4050bf0dddfee3ddaa5f847076b8822f", + "0000000074c108842c3ec2252bba62db4050bf0dddfee3ddaa5f847076b8822f", 26959535291011309493156476344723991336010898738574164086137773096960 - ], + ], [ - "0000000067dc2f84a73fbf5d3c70678ce4a1496ef3a62c557bc79cbdd1d49f22", + "0000000067dc2f84a73fbf5d3c70678ce4a1496ef3a62c557bc79cbdd1d49f22", 26959535291011309493156476344723991336010898738574164086137773096960 - ], + ], [ - "00000000dbf06f47c0624262ecb197bccf6bdaaabc2d973708ac401ac8955acc", + "00000000dbf06f47c0624262ecb197bccf6bdaaabc2d973708ac401ac8955acc", 26959535291011309493156476344723991336010898738574164086137773096960 - ], + ], [ - "000000009260fe30ec89ef367122f429dcc59f61735760f2b2288f2e854f04ac", + "000000009260fe30ec89ef367122f429dcc59f61735760f2b2288f2e854f04ac", 26959535291011309493156476344723991336010898738574164086137773096960 - ], + ], [ - "00000000f9f1a700898c4e0671af6efd441eaf339ba075a5c5c7b0949473c80b", + "00000000f9f1a700898c4e0671af6efd441eaf339ba075a5c5c7b0949473c80b", 26959535291011309493156476344723991336010898738574164086137773096960 - ], + ], [ - "000000005107662c86452e7365f32f8ffdc70d8d87aa6f78630a79f7d77fbfe6", + "000000005107662c86452e7365f32f8ffdc70d8d87aa6f78630a79f7d77fbfe6", 26959535291011309493156476344723991336010898738574164086137773096960 - ], + ], [ - "00000000984f962134a7291e3693075ae03e521f0ee33378ec30a334d860034b", + "00000000984f962134a7291e3693075ae03e521f0ee33378ec30a334d860034b", 22791060871177364286867400663010583169263383106957897897309909286912 - ], + ], [ - "000000005e36047e39452a7beaaa6721048ac408a3e75bb60a8b0008713653ce", + "000000005e36047e39452a7beaaa6721048ac408a3e75bb60a8b0008713653ce", 20657664212610420653213483117824978239553266057163961604478437687296 - ], + ], [ - "00000000128d789579ffbec00203a371cbb39cee27df35d951fd66e62ed59258", + "00000000128d789579ffbec00203a371cbb39cee27df35d951fd66e62ed59258", 20055820920770189543295303139304627292355830414308479769458683936768 - ], + ], [ - "000000008dde642fb80481bb5e1671cb04c6716de5b7f783aa3388456d5c8a85", + "000000008dde642fb80481bb5e1671cb04c6716de5b7f783aa3388456d5c8a85", 14823939180767414932263578623363531361763221729526512593941781544960 - ], + ], [ - "000000008135b689ad1557d4e148a8b9e58e2c4a67240fc87962abb69710231a", + "000000008135b689ad1557d4e148a8b9e58e2c4a67240fc87962abb69710231a", 10665477591887247494381404907447500979192021944764506987270680608768 - ], + ], [ - "00000000308496ef3e4f9fa542a772df637b4aaf1dcce404424611feacfc09e7", + "00000000308496ef3e4f9fa542a772df637b4aaf1dcce404424611feacfc09e7", 7129927859545590787920041835044506526699926406309469412482969763840 - ], + ], [ - "000000001a2e0c63d7d012003c9173acfd04ccd6372027718979228c461b5ed5", + "000000001a2e0c63d7d012003c9173acfd04ccd6372027718979228c461b5ed5", 5949911473257063494842414979623989957440207170696926280907451531264 - ], + ], [ - "000000002e0c0ac26ccde91b51ab018576b3a126b413e9f6f787b36637f1b174", + "000000002e0c0ac26ccde91b51ab018576b3a126b413e9f6f787b36637f1b174", 5905492491837656485645884063467495540781288435542782321354050895872 - ], + ], [ - "00000000103226f85fe2b68795f087dcec345e523363f18017e60b5c94175355", + "00000000103226f85fe2b68795f087dcec345e523363f18017e60b5c94175355", 4430143390146946405787502162943966061454423600514874825749833973760 - ], + ], [ - "000000001ae6f66fd4de47f8d6f357e798943bbfc4f39ebf14b0975fab059173", + "000000001ae6f66fd4de47f8d6f357e798943bbfc4f39ebf14b0975fab059173", 3447600406241317909690675945127070282093452846402311540118831235072 - ], + ], [ - "000000000a3f22690162744d3bc0b674c92e661a25afb3d2ac8b39b27ac14373", + "000000000a3f22690162744d3bc0b674c92e661a25afb3d2ac8b39b27ac14373", 2351604382534916182160036119666703740669209516522695514729880748032 - ], + ], [ - "0000000006dc436c3c515a97446af858c1203a501c85d26c4a30afa380aba4a1", + "0000000006dc436c3c515a97446af858c1203a501c85d26c4a30afa380aba4a1", 2098151686442211199940455690614286210348997571531298297574806519808 - ], + ], [ - "000000000943fe1680ffcc498ce50790ff8e842a8af2c157664e4fbc1cb7cb46", + "000000000943fe1680ffcc498ce50790ff8e842a8af2c157664e4fbc1cb7cb46", 2275790652544821279950241890112140030244814501479017131553197129728 - ], + ], [ - "000000000847b2144376c1fb057ea1d5a027d5a6004277ed4c72422e93df04e9", + "000000000847b2144376c1fb057ea1d5a027d5a6004277ed4c72422e93df04e9", 1622203955679450683159610732218403647246163922223729367236739072000 - ], + ], [ - "00000000094505954deb1d31382b86d0510fd280a34143400b1856a4d52b4c93", + "00000000094505954deb1d31382b86d0510fd280a34143400b1856a4d52b4c93", 1551048739079662593758612650769536967206480773659027300489594142720 - ], + ], [ - "000000000109272cecb3f7e98ac12cf149fa8a1b2aaab248e1b006b0dc595a3a", + "000000000109272cecb3f7e98ac12cf149fa8a1b2aaab248e1b006b0dc595a3a", 1389323280429349294447518501872137680563441219958739463959193059328 - ], + ], [ - "0000000009e6aa0fe39b790625ffeb18a2d6ff5060a5bd14e699e83c54109977", + "0000000009e6aa0fe39b790625ffeb18a2d6ff5060a5bd14e699e83c54109977", 1147152896345386682952518188670047452875537662186691235300769792000 - ], + ], [ - "0000000000d14af55c4eae0121184919baba2deb8bf89c3af6b8e4c4f35c8e4e", + "0000000000d14af55c4eae0121184919baba2deb8bf89c3af6b8e4c4f35c8e4e", 594007861936424273334637371358095438347537381057796937154824241152 - ], + ], [ - "0000000003dfbfa2b33707e691ab2ab7cda7503be2c2cce43d1b21cd1cc757fb", + "0000000003dfbfa2b33707e691ab2ab7cda7503be2c2cce43d1b21cd1cc757fb", 148501965484106068333659342839523859586884345264449234288706060288 - ], + ], [ - "0000000000c169d181d66d242901f70d006f3e088c1ae9cacb88b94b8266e9c3", + "0000000000c169d181d66d242901f70d006f3e088c1ae9cacb88b94b8266e9c3", 110393429764504113949181711819653188468070301266890302199533928448 - ], + ], [ - "000000000009f7d1439d6a2fc1a456db8e843674275bf0133fc7b43b5f45b96e", + "000000000009f7d1439d6a2fc1a456db8e843674275bf0133fc7b43b5f45b96e", 76554528428498296726819074079132986384157750623812250673757552640 - ], + ], [ - "000000000011b8a8fad7973548b50f6d4b2ba1690f7487c374e43248c576354f", + "000000000011b8a8fad7973548b50f6d4b2ba1690f7487c374e43248c576354f", 52678642966898219212816601311127992435882858542187514726849708032 - ], + ], [ - "000000000077e856b6cc475d9cf784119811214c9cac8d7b674ec24faa7c2c0c", + "000000000077e856b6cc475d9cf784119811214c9cac8d7b674ec24faa7c2c0c", 43246870766561725070861386869077695524372774526710079316876591104 - ], + ], [ - "00000000004cbb474f2cbf3a65f690efa09804512af3351ba3a0888c806c6625", + "00000000004cbb474f2cbf3a65f690efa09804512af3351ba3a0888c806c6625", 37817516728945957090904676150631917288430706594442690521085247488 - ], + ], [ - "0000000000235b1ec6656d8e91f3dde3b6ab9ad7e75b332e4da9355ce60d860e", + "0000000000235b1ec6656d8e91f3dde3b6ab9ad7e75b332e4da9355ce60d860e", 29373101246077110899697012205905070265841442578602225419818106880 - ], + ], [ - "00000000002a153a2c95a8e5493db93086b0e3fe590b636a5871ace57523ef93", + "00000000002a153a2c95a8e5493db93086b0e3fe590b636a5871ace57523ef93", 20444488966645742314409346972440253478913291170842138088329707520 - ], + ], [ - "00000000000e9550e084908cf91a4e8b74f9f1315d1bc4020709f9e7f261bb18", + "00000000000e9550e084908cf91a4e8b74f9f1315d1bc4020709f9e7f261bb18", 19563849255781403323327768731100757126732627316116500830377476096 - ], + ], [ - "00000000002c2cfef3bb85b463d3fcd39b73a6d3d5ae11c1e2a8113e3794f28d", + "00000000002c2cfef3bb85b463d3fcd39b73a6d3d5ae11c1e2a8113e3794f28d", 12545026348036226200394850922278603223904369245268262607334146048 - ], + ], [ - "00000000000fa92b757ee29674aa97e98a49ba3ad340d2baa94155d71648dfe1", + "00000000000fa92b757ee29674aa97e98a49ba3ad340d2baa94155d71648dfe1", 8719867261221084516486306056196045840260667577454435863762042880 - ], + ], [ - "0000000000030571601dbc8e13d00d45004eee6ea8b6ab3cdfb38d2546fee21c", + "0000000000030571601dbc8e13d00d45004eee6ea8b6ab3cdfb38d2546fee21c", 5942996718418989293499865695368015163438891473576991811912597504 - ], + ], [ - "00000000000bb6adef42e63082b20fd2b1dc1b324c51973512a4c31f29a9986e", + "00000000000bb6adef42e63082b20fd2b1dc1b324c51973512a4c31f29a9986e", 3926013280397599483741094494745234959951218212740030386090803200 - ], + ], [ - "000000000000765094788a98dbb8adac30d248b7129b59b1441ee2b7ef9e332f", + "000000000000765094788a98dbb8adac30d248b7129b59b1441ee2b7ef9e332f", 3337321571246095014985518819479127172783474909736415373333364736 - ], + ], [ - "00000000000431a0aa9625f82975709f3c6f4f64d04c559512af051599872084", + "00000000000431a0aa9625f82975709f3c6f4f64d04c559512af051599872084", 2200419182034594781720344474937177839165432393990533906392154112 - ], + ], [ - "00000000000292b850b8f8578e6b4d03cbb4a78ada44afbb4d2f80a16490e8f9", + "00000000000292b850b8f8578e6b4d03cbb4a78ada44afbb4d2f80a16490e8f9", 1861311314983800126815643622927230076368334845814253369901973504 - ], + ], [ - "0000000000025afe84e27423011af25f777e5a94545dbd00fd04bebe9050f7dd", + "0000000000025afe84e27423011af25f777e5a94545dbd00fd04bebe9050f7dd", 1653206561150525499452195696179626311675293455763937233695932416 - ], + ], [ - "0000000000000e389cccae2a40437be574fd806909e24136711e7f8bce671d65", + "0000000000000e389cccae2a40437be574fd806909e24136711e7f8bce671d65", 1462200632444444190489436459820840230299714881944341127503020032 - ], + ], [ - "0000000000030510bf6bc1649726cf2e6e4010c64a2c8fd3fde5dc92535ca40e", + "0000000000030510bf6bc1649726cf2e6e4010c64a2c8fd3fde5dc92535ca40e", 1224744150896501443874292381730317417444978877835711165914677248 - ], + ], [ - "00000000000082648057f14fc835779c6ce46a407bafb2e5c2ac1d20d9f4e822", + "00000000000082648057f14fc835779c6ce46a407bafb2e5c2ac1d20d9f4e822", 1036989760889350435547200084292752907272941324136347429599444992 - ], + ], [ - "000000000000f38accd6b22959010471a6d9f159d43bf2a9d4c53c220201254e", + "000000000000f38accd6b22959010471a6d9f159d43bf2a9d4c53c220201254e", 739430030225080220618328322475016688484025266646974337550123008 - ], + ], [ - "0000000000004ed7a73133678b5eb883cd8882bf14dfb26c104ae0c3f94cf4ee", + "0000000000004ed7a73133678b5eb883cd8882bf14dfb26c104ae0c3f94cf4ee", 484975157177710342494716926626447514974484083994735770500857856 - ], + ], [ - "00000000000037bb3ff4cf649a1757d4028ecc10f893529b4a2214792c981f96", + "00000000000037bb3ff4cf649a1757d4028ecc10f893529b4a2214792c981f96", 353833947722011807976659613996792948209273674048993161457434624 - ], + ], [ - "0000000000008008f46559fe7f181e9dc0648f213472a1e576e8bf506b88f22f", + "0000000000008008f46559fe7f181e9dc0648f213472a1e576e8bf506b88f22f", 390843739553851677760235428436025349398613161749553108945469440 - ], + ], [ - "000000000000691d0c2444db713bf6c088844cc95a37cdc55cc269bb0a31d8c8", + "000000000000691d0c2444db713bf6c088844cc95a37cdc55cc269bb0a31d8c8", 327394795212563108599383268946242257264650552916910648089116672 - ], + ], [ - "00000000000071153b0afcc64a425f8442c29749610797119e732dd4b723f675", + "00000000000071153b0afcc64a425f8442c29749610797119e732dd4b723f675", 291935447509363748964474894494542149680088347011133317125767168 - ], + ], [ - "000000000000a384acb522e4e5935ad2bc31366ecf1f16f1f11023e967ef033d", + "000000000000a384acb522e4e5935ad2bc31366ecf1f16f1f11023e967ef033d", 245823858161213192073337185391658632187400443916100519594033152 - ], + ], [ - "0000000000002e532093d43e901292121fb7c6583caf2d13b666fe7e194b4a97", + "0000000000002e532093d43e901292121fb7c6583caf2d13b666fe7e194b4a97", 171262555713783851185422181139260521316022447660158187451973632 - ], + ], [ - "00000000000033e435c4bbddc7eb255146aa7f18e61a832983af3a9ee5dd144d", + "00000000000033e435c4bbddc7eb255146aa7f18e61a832983af3a9ee5dd144d", 110438984653392107399822606842181601255647711092336854093004800 - ], + ], [ - "00000000000028ff4b0bd45f0e3e713f91fa1821d28a276a1a1f32f786662f13", + "00000000000028ff4b0bd45f0e3e713f91fa1821d28a276a1a1f32f786662f13", 61993465896324436412959469550829248888675813063783317791309824 - ], + ], [ - "0000000000001ef9c75318e116a607af4de68fb4f67c788677ee6779fb5fa0d5", + "0000000000001ef9c75318e116a607af4de68fb4f67c788677ee6779fb5fa0d5", 47525089675259291211422247200069659468817014361857087365971968 - ], + ], [ - "0000000000000e6e98694ccb8247aad63aaa1e2bec5a7be14329407e4cea6223", + "0000000000000e6e98694ccb8247aad63aaa1e2bec5a7be14329407e4cea6223", 30742228348699538311994447367921718297595975288392383715082240 - ], + ], [ - "000000000000000a2153574b2523a6d1844c3cb82d085e2575846dd8c5d4ebb4", + "000000000000000a2153574b2523a6d1844c3cb82d085e2575846dd8c5d4ebb4", 19547336162709893274575855467812492508787617050928192350584832 - ], + ], [ - "00000000000002a92c1b1ffb2a8388979cf30798e312335ae2a1b922927ee83d", + "00000000000002a92c1b1ffb2a8388979cf30798e312335ae2a1b922927ee83d", 17248274092338559882155796390905381469049315669915374897332224 - ], + ], [ - "00000000000004d54b1422ce733922e7672a4e2ecc86dcf96c0de06565cddaa6", + "00000000000004d54b1422ce733922e7672a4e2ecc86dcf96c0de06565cddaa6", 15943936487596784557029840069157210316687734428242467413295104 - ], + ], [ - "00000000000009dd91ae96cbbf67af42340b0bc715b3606aa725f630b470262d", + "00000000000009dd91ae96cbbf67af42340b0bc715b3606aa725f630b470262d", 14273467308195657992975774342458504496649432985410431166185472 - ], + ], [ - "00000000000007d33d78522fa95bdcd4a25072aeac844cbe9b6bc5d0cc885d0a", + "00000000000007d33d78522fa95bdcd4a25072aeac844cbe9b6bc5d0cc885d0a", 14930233597189143322113827544414041000381079823613435714732032 - ], + ], [ - "00000000000003dd57f5dd1228f68390b586700063225d26bac972bd120546d2", + "00000000000003dd57f5dd1228f68390b586700063225d26bac972bd120546d2", 15164766714763258952996988973449124317842091658872414191747072 - ], + ], [ - "000000000000076bdeca878b47c392f51fbda543b1e69612cf7d305deb537604", + "000000000000076bdeca878b47c392f51fbda543b1e69612cf7d305deb537604", 15357836632983707094928406965317628870031114888441593128288256 - ], + ], [ - "00000000000008eb1bb7e18d9dfe62210d761cbf114d59ca08e4f638b8563e30", + "00000000000008eb1bb7e18d9dfe62210d761cbf114d59ca08e4f638b8563e30", 15958672964717750944291813934170287689797412223641384931819520 - ], + ], [ - "00000000000001b0d8d885e4d77d7c51e8f1fdaba68f229ac04d191915845f09", + "00000000000001b0d8d885e4d77d7c51e8f1fdaba68f229ac04d191915845f09", 18362361570655080300849714079315004638119732162003921272832000 - ], + ], [ - "000000000000081baa3a716d5f9ab072c9fc3b798900234c9be23ab02a287c30", + "000000000000081baa3a716d5f9ab072c9fc3b798900234c9be23ab02a287c30", 22401652017447755518156310839596703571934659990690572544245760 - ], + ], [ - "00000000000005b88d0224b9b0d4b65d3de9a61d93609bb91c9297440f1c4657", + "00000000000005b88d0224b9b0d4b65d3de9a61d93609bb91c9297440f1c4657", 22607619418140130980719672680045705126213018528712048676700160 - ], + ], [ - "000000000000027d6a6870403fa43a650b7d9a6e61243f375a79ea935ad9ef1f", + "000000000000027d6a6870403fa43a650b7d9a6e61243f375a79ea935ad9ef1f", 24717289559589094364468373797949472355802981654048927838633984 - ], + ], [ - "0000000000000810a3490b86e4f302f6557f9621c5c8620c2b09ec8f0cf72794", + "0000000000000810a3490b86e4f302f6557f9621c5c8620c2b09ec8f0cf72794", 23340814324747679919001773364939281849550099124416593832968192 - ], + ], [ - "000000000000073833bca8d0ea909fde717e251576b7b3ccaaa58ad5d39eed60", + "000000000000073833bca8d0ea909fde717e251576b7b3ccaaa58ad5d39eed60", 23242391331131109072962566885467580392541369223033474166816768 - ], + ], [ - "000000000000031b7fd2ed1f28ff74e969aa891297706c38bd2e1d3bc48183c4", + "000000000000031b7fd2ed1f28ff74e969aa891297706c38bd2e1d3bc48183c4", 21554562042243053719921017803645315870071034703425342074257408 - ], + ], [ - "0000000000000b0738bcba382983811d40b531f2e68cd57126092755f1be4ba6", + "0000000000000b0738bcba382983811d40b531f2e68cd57126092755f1be4ba6", 20615546854515052444405957679617344022137222968655050411343872 - ], + ], [ - "000000000000000664cbfd5e3fa497c07614c33a0934b83e01fbe980634a9aa4", + "000000000000000664cbfd5e3fa497c07614c33a0934b83e01fbe980634a9aa4", 19540887421473929614259883543522244007742949396702043752628224 - ], + ], [ - "000000000000021eb520df39289a70e40c59822a8c47924dc4940e7d0c1455c4", + "000000000000021eb520df39289a70e40c59822a8c47924dc4940e7d0c1455c4", 19588382523276445241758125434587686389961661359576757951266816 - ], + ], [ - "0000000000000275e0c41b11bc250fe887c5e60c8ebaaa449f5c28c67133d496", + "0000000000000275e0c41b11bc250fe887c5e60c8ebaaa449f5c28c67133d496", 18009299117968233362105684657812007807160912568078774269116416 - ], + ], [ - "000000000000097fb0fdbeee0cee7e8f4e1a4ef8fad49f3d549624b0d47abed0", + "000000000000097fb0fdbeee0cee7e8f4e1a4ef8fad49f3d549624b0d47abed0", 17993483763986497389087426516491816616385967180337839494660096 - ], + ], [ - "000000000000053f199ae19d34365277e534f978ea2f6c69cd4757a4fc099af5", + "000000000000053f199ae19d34365277e534f978ea2f6c69cd4757a4fc099af5", 16574638092431222848464934504874974361824393751455373256032256 - ], + ], [ - "0000000000000217b2e7b4f61682d24b9357d62ad29f27ed45ea2a32dc1f32f6", + "0000000000000217b2e7b4f61682d24b9357d62ad29f27ed45ea2a32dc1f32f6", 17085559845791583266730740536950670241169412424878408752693248 - ], + ], [ - "000000000000039c1d77acd4702393f48ca61983c64fc0209ade141c694b2359", + "000000000000039c1d77acd4702393f48ca61983c64fc0209ade141c694b2359", 17870687961287995446644888885900316642120964851955511819501568 - ], + ], [ - "0000000000000ae53f0c78330f6c2fbece2752909bc3742823e4fab29c5fd2b0", + "0000000000000ae53f0c78330f6c2fbece2752909bc3742823e4fab29c5fd2b0", 15554707140145502641228553657813466188995512591033787398225920 - ], + ], [ - "00000000000004b4d72b8631a85ec7d226dc696f1913ba1bf735b7c8dec207b8", + "00000000000004b4d72b8631a85ec7d226dc696f1913ba1bf735b7c8dec207b8", 16944226977030767532657500340718760127019357828074148225613824 - ], + ], [ - "00000000000006e06735bffb7d2f215dcadd8311fc33f4a46661fdca3dc0560e", + "00000000000006e06735bffb7d2f215dcadd8311fc33f4a46661fdca3dc0560e", 17028747171100603034973679895960153979114298528140818252824576 - ], + ], [ - "000000000000055fc0110d4a38ffb338eabc30c8b0aef355d4643d21b5b6a860", + "000000000000055fc0110d4a38ffb338eabc30c8b0aef355d4643d21b5b6a860", 15614535766060906942258863525753414259523988166363835227176960 - ], + ], [ - "000000000000081b69cb4de006c14084c4861f0e4a140c37200117a738733fe8", + "000000000000081b69cb4de006c14084c4861f0e4a140c37200117a738733fe8", 15392654931672180089790308609774483894682932641297604569726976 - ], + ], [ - "00000000000009920770f2d40b5b6a8aba33d969b855c91b0f56e3db9c27e41a", + "00000000000009920770f2d40b5b6a8aba33d969b855c91b0f56e3db9c27e41a", 14444739009842829731785903206212823051010663269705670545375232 - ], + ], [ - "0000000000000791dd1cb7a684a54c72ccde51f459fff0fc3e6e051641b1e941", + "0000000000000791dd1cb7a684a54c72ccde51f459fff0fc3e6e051641b1e941", 13237058963854547748734324548161076199478283141947127217782784 - ], + ], [ - "000000000000019da474a1a598b5cf28534b7fd9b214eed0f36c67c203a9b449", + "000000000000019da474a1a598b5cf28534b7fd9b214eed0f36c67c203a9b449", 12305424274651356593961118223415860240572779254789271782948864 - ], + ], [ - "000000000000074333e888bac730f9772b65e4cc9d07edb122c6e3c6606bc8ab", + "000000000000074333e888bac730f9772b65e4cc9d07edb122c6e3c6606bc8ab", 11046080738989403765716562970384822165842244193743674858799104 - ], + ], [ - "000000000000067080669115c445f378f3dec19787558d0e03263b9dec5d7720", + "000000000000067080669115c445f378f3dec19787558d0e03263b9dec5d7720", 10007073282210984973971337419529346944295676968729147521105920 - ], + ], [ - "0000000000000304760bf583f4ac241c5ffe77312fa213634eba252c720530f1", + "0000000000000304760bf583f4ac241c5ffe77312fa213634eba252c720530f1", 9412783771427520201810837309176674245361798887059324066070528 - ], + ], [ - "000000000000041fb61665c8a31b8b5c3ae8fe81903ea81530c979d5094e6f9d", + "000000000000041fb61665c8a31b8b5c3ae8fe81903ea81530c979d5094e6f9d", 8825801199382903987726989797449454220615414953524072026210304 - ], + ], [ - "000000000000022fc7f2a5c87b2bab742d71c4eb662d572df33f18193d6abf0e", + "000000000000022fc7f2a5c87b2bab742d71c4eb662d572df33f18193d6abf0e", 8774971387283464186072960143252932765613148614319486309236736 - ], + ], [ - "000000000000013c6d43ba38bc5f24e699515b9d78602694112fefdc64606640", + "000000000000013c6d43ba38bc5f24e699515b9d78602694112fefdc64606640", 8158785580212107593904235970576336449063725988071903546310656 - ], + ], [ - "00000000000001665176b9a810fddf27cca60dfcfd80bf113289fcc8ffed0284", + "00000000000001665176b9a810fddf27cca60dfcfd80bf113289fcc8ffed0284", 8002789794116287035234223109988652176644807295346590313611264 - ], + ], [ - "00000000000002dc6ef80f56a00f1091471d942ce9bfb656ebdab4ea0b77eb0b", + "00000000000002dc6ef80f56a00f1091471d942ce9bfb656ebdab4ea0b77eb0b", 7839560629067579481152758851432818444879208153964570478641152 - ], + ], [ - "00000000000002a1fa5546ec48ca88b9e5710e2c6d895bb3675004fdacd6ab13", + "00000000000002a1fa5546ec48ca88b9e5710e2c6d895bb3675004fdacd6ab13", 7999430563890709006856701613305138698914315019190763857641472 - ], + ], [ - "00000000000000f517517c11e649b98feca7da84ae44fb643de5a86798fe3c31", + "00000000000000f517517c11e649b98feca7da84ae44fb643de5a86798fe3c31", 9047927233058169382412882048952728634925849476849852060008448 - ], + ], [ - "0000000000000299cab92a923348acf9251f656bcbacdb641fd0a66d895a6e8f", + "0000000000000299cab92a923348acf9251f656bcbacdb641fd0a66d895a6e8f", 8296391419817537486273948666838217011279219811331013552898048 - ], + ], [ - "000000000000027508b977f72c3a0f06f1f36e311ad079536630661880934501", + "000000000000027508b977f72c3a0f06f1f36e311ad079536630661880934501", 9081029136740872581753422344739175313292014241889017867010048 - ], + ], [ - "00000000000001925959229452cc6fbfef0104ebed7ccd6f584f2439c5dd1f1b", + "00000000000001925959229452cc6fbfef0104ebed7ccd6f584f2439c5dd1f1b", 8230751570811169734692743946971314968326461977249645504495616 - ], + ], [ - "00000000000003b34ca89509da5f558af468c194afaa8d458bbeb07c50cc7c74", + "00000000000003b34ca89509da5f558af468c194afaa8d458bbeb07c50cc7c74", 7384127474250891166670391848516180960454656786677558849568768 - ], + ], [ - "0000000000000076559e314ab0c86cc552e34fd79488415d3d17f6ea3c01adb3", + "0000000000000076559e314ab0c86cc552e34fd79488415d3d17f6ea3c01adb3", 6172230000534146257480611019445716458048957888854766248787968 - ], + ], [ - "000000000000003a58043252cdc30ed2f37fb17e6ef1658324b1478f16c1463b", + "000000000000003a58043252cdc30ed2f37fb17e6ef1658324b1478f16c1463b", 5561365017980676031428107027647386014985059524839404952616960 - ], + ], [ - "000000000000011babf767e60240658195b693711c217d7da0d9215ccab45333", + "000000000000011babf767e60240658195b693711c217d7da0d9215ccab45333", 4026319404534786334009451711043898716884778820756489262596096 - ], + ], [ - "000000000000027579d28fb480ccad8e2516d1219d4c1919e3fd4fc0c882955d", + "000000000000027579d28fb480ccad8e2516d1219d4c1919e3fd4fc0c882955d", 3513558656525386849113615662535622466519417660386833443323904 - ], + ], [ - "0000000000000074546fe07f80ba15fc81897ec56a5535de727df9fda9dab500", + "0000000000000074546fe07f80ba15fc81897ec56a5535de727df9fda9dab500", 3004083578955603829930099910053556479043735076695139267117056 - ], + ], [ - "00000000000000b6c55833b80c07894f4c4d3bb686e5ddbc1b1d162e22752ca3", + "00000000000000b6c55833b80c07894f4c4d3bb686e5ddbc1b1d162e22752ca3", 2675541054922611112919804040984964595022815308724929898217472 - ], + ], [ - "00000000000001326f2f970753122e35bfdf3358d046ddf5ea22e57f5d82b00d", + "00000000000001326f2f970753122e35bfdf3358d046ddf5ea22e57f5d82b00d", 2409843108029446766213067266805752590003732794677225687351296 - ], + ], [ - "00000000000000641084745613912464ff73c974bafd0bf6dd306295f019d306", + "00000000000000641084745613912464ff73c974bafd0bf6dd306295f019d306", 2218268905456883731807407021635746739577921454491297946533888 - ], + ], [ - "000000000000011ae105ddb1a5bbac6931a6578d95c201525f3a945276a64559", + "000000000000011ae105ddb1a5bbac6931a6578d95c201525f3a945276a64559", 1727551573307299192250197436766000536509732237655131060961280 - ], + ], [ - "00000000000000d9b66fee19af89eaaf3f3933d1acd2617924c107f0abbe0a41", + "00000000000000d9b66fee19af89eaaf3f3933d1acd2617924c107f0abbe0a41", 1394031503757574068227953656553224448260418805016069352194048 - ], + ], [ - "0000000000000011956d42670c2f75eeb344ac0657a806775998e2c58fa4b157", + "0000000000000011956d42670c2f75eeb344ac0657a806775998e2c58fa4b157", 1263610003247723462826224891154624535497729630761756072607744 - ], + ], [ - "00000000000000959b1ea990368fd16d494e68ee13bd7245ddd9cdfba3330100", + "00000000000000959b1ea990368fd16d494e68ee13bd7245ddd9cdfba3330100", 1030450001678223668360152541055867895065240185756254103142400 - ], + ], [ - "0000000000000091f86b1e423e24fe358c72db181cfcc2738c85f2f51871a960", + "0000000000000091f86b1e423e24fe358c72db181cfcc2738c85f2f51871a960", 862513010327976103705811440432628413487564277790886242287616 - ], + ], [ - "0000000000000055e146e473b49fe656a1f2f4b8c33e72b80acc18f84d9fcc26", + "0000000000000055e146e473b49fe656a1f2f4b8c33e72b80acc18f84d9fcc26", 720982641204331278205950312227594303241470815982254303477760 - ], + ], [ - "000000000000004f6a191a3261274735292bc30a1f79f23a143e4ee7dd2f64c1", + "000000000000004f6a191a3261274735292bc30a1f79f23a143e4ee7dd2f64c1", 530591525189316709998942710962548491505413142398652303540224 - ], + ], [ - "000000000000005327c8e714272803c60277333362e74ec88b9ffab5410c2358", + "000000000000005327c8e714272803c60277333362e74ec88b9ffab5410c2358", 410030579894253754102159787320079652501746816512444002729984 - ], + ], [ - "0000000000000002e2a62b8705564c38d6a746fc8e971a450a69989152b5ee97", + "0000000000000002e2a62b8705564c38d6a746fc8e971a450a69989152b5ee97", 310118479516817784682897231521434079438159381558537557639168 - ], + ], [ - "00000000000000202bf3ff30109538bfd9b5075c6438ab5ef64ebe2cf9b61404", + "00000000000000202bf3ff30109538bfd9b5075c6438ab5ef64ebe2cf9b61404", 239366800071949252578530950352093786414793290792735831228416 - ], + ], [ - "000000000000001c997105893f5991cb45765ff856b6e503f8466cb22cdd330a", + "000000000000001c997105893f5991cb45765ff856b6e503f8466cb22cdd330a", 181156297885756721946540202079438048595571151633323613224960 - ], + ], [ - "0000000000000010c13ce182a3d8fc6748b75640447eb360d7739a5fe984ffc1", + "0000000000000010c13ce182a3d8fc6748b75640447eb360d7739a5fe984ffc1", 142431093377788751676361246670241704468765375727695350988800 - ], + ], [ - "000000000000000bbb49db68b79ecc8393376d78272d237bb612288af64c1de8", + "000000000000000bbb49db68b79ecc8393376d78272d237bb612288af64c1de8", 100696259189502783924473792493100546893980348528488767029248 - ], + ], [ - "0000000000000001bbfd0973c367d30eef2416d9e94bdddea53bccf541a4858f", + "0000000000000001bbfd0973c367d30eef2416d9e94bdddea53bccf541a4858f", 68962778243821519216393853205209897734463141354237780295680 - ], + ], [ - "0000000000000004ee5b6ace996ab746f1e6dd952cdbc74c0b4f8b9ac51c7335", + "0000000000000004ee5b6ace996ab746f1e6dd952cdbc74c0b4f8b9ac51c7335", 52765641310467331636297188681879886184148735229489015947264 - ], + ], [ - "0000000000000002f2f23b515085d0c9f37a2824304ccb7ca1546a48548d0dac", + "0000000000000002f2f23b515085d0c9f37a2824304ccb7ca1546a48548d0dac", 44233472386696495417387091608220539804351405166731810832384 - ], + ], [ - "00000000000000045590c3fdeca1753d148a87614a70fa0897a17f90bb321654", + "00000000000000045590c3fdeca1753d148a87614a70fa0897a17f90bb321654", 38110290672195532365762668664552282566878756832852091863040 - ], + ], [ - "0000000000000002b704edc0bf1435fe2116040b547adb1bc2d196eb81779834", + "0000000000000002b704edc0bf1435fe2116040b547adb1bc2d196eb81779834", 29679649578007061283718812081441644170496168236939550392320 - ], + ], [ - "00000000000000038cc59dc6dd68ae0fbe2ded8a3de65dbd9a2f9a36d26772df", + "00000000000000038cc59dc6dd68ae0fbe2ded8a3de65dbd9a2f9a36d26772df", 22829202948393929850749706076701368331072452018388575715328 - ], + ], [ - "0000000000000000a979bc50075e7cdf0da5274f7314910b2d798b1aeaf6543f", + "0000000000000000a979bc50075e7cdf0da5274f7314910b2d798b1aeaf6543f", 19005913916847449503306572434028937600915626422125897711616 - ], + ], [ - "0000000000000001dd8e548c8cf5b77cde6e5631cd542e39f42c41952e5e7085", + "0000000000000001dd8e548c8cf5b77cde6e5631cd542e39f42c41952e5e7085", 15065005852539512185984435657022720640916062598235628240896 - ], + ], [ - "0000000000000002513542a461de351a5a94f96b4bcd3e324a48d2d71b403fe0", + "0000000000000002513542a461de351a5a94f96b4bcd3e324a48d2d71b403fe0", 12288698618318346282960995223961541766142764336009759948800 - ], + ], [ - "000000000000000150cc07163e78d599a7e56c0d1040641bffb382705ac17df0", + "000000000000000150cc07163e78d599a7e56c0d1040641bffb382705ac17df0", 10284386012808371892335572105827331142617405906583881252864 - ], + ], [ - "00000000000000009051d83d276dad5c547612f67c2907acf6a143039bddb1bb", + "00000000000000009051d83d276dad5c547612f67c2907acf6a143039bddb1bb", 8614444778121073626993210829679478604092861119379437256704 - ], + ], [ - "00000000000000000b83d3947d2790ab0bcbbb61eba1eb8d8f0f0eb3e9d461e0", + "00000000000000000b83d3947d2790ab0bcbbb61eba1eb8d8f0f0eb3e9d461e0", 7065379129219572345353864175298106702426244380437224882176 - ], + ], [ - "00000000000000005a4fbbaeffee6d52fa329dd8c559f90c9b30264c46ad33fd", + "00000000000000005a4fbbaeffee6d52fa329dd8c559f90c9b30264c46ad33fd", 6343094824615218102798845742064326605321937397913065881600 - ], + ], [ - "00000000000000006b6834bae83e895a78c5026a8c8141388040d90506cf3148", + "00000000000000006b6834bae83e895a78c5026a8c8141388040d90506cf3148", 5384518863803604621895699676581808210968416076987222720512 - ], + ], [ - "0000000000000000bf3c066c9acdb008e7fff3672f1391b35c8877b76b9e295e", + "0000000000000000bf3c066c9acdb008e7fff3672f1391b35c8877b76b9e295e", 4405349994161605759458363322921957536960017949107037405184 - ], + ], [ - "00000000000000006bcf448b771c8f4db4e2ca653474e3b29504ec08422b3fba", + "00000000000000006bcf448b771c8f4db4e2ca653474e3b29504ec08422b3fba", 3863038134637689339706803268689141874606936642244315185152 - ], + ], [ - "000000000000000098686ab04cc22fec77e4fa2d76d5a3cc0eb8cbf4ed800cdc", + "000000000000000098686ab04cc22fec77e4fa2d76d5a3cc0eb8cbf4ed800cdc", 3369574570478873127315415525946742317481702644901195284480 - ], + ], [ - "000000000000000036cc637d80982595b1fa30f877efe8904965e6fd70aeae1a", + "000000000000000036cc637d80982595b1fa30f877efe8904965e6fd70aeae1a", 3045099693687311168583241534842989903432036285033490677760 - ], + ], [ - "00000000000000000ee9b585e0a707347d7c80f3a905f48fa32d448917335366", + "00000000000000000ee9b585e0a707347d7c80f3a905f48fa32d448917335366", 2578448441038522347123624842639328775756428679710156783616 - ], + ], [ - "00000000000000000401800189014bad6a3ca1af029e19b362d6ef3c5425a8dc", + "00000000000000000401800189014bad6a3ca1af029e19b362d6ef3c5425a8dc", 2293149852232440455888971398133692017055281498246925516800 - ], + ], [ - "00000000000000001b44d4645ac00773be676f3de8a8bff1a5fdd1fb04d2b3b2", + "00000000000000001b44d4645ac00773be676f3de8a8bff1a5fdd1fb04d2b3b2", 2002553378451099534811946324256852041059202347552707969024 - ], + ], [ - "00000000000000003ff2a53152ee98910d7383c0177459ad258c4b2d2c4d4610", + "00000000000000003ff2a53152ee98910d7383c0177459ad258c4b2d2c4d4610", 1602972750958019380418919163663316163747908621623690788864 - ], + ], [ - "00000000000000001bb242c9463b511b9e6a99a6d48bd783acb070ca27861c2b", + "00000000000000001bb242c9463b511b9e6a99a6d48bd783acb070ca27861c2b", 1555090122338762644529309082074529684497336694348804259840 - ], + ], [ - "000000000000000019d43247356b848a7ef8b1c786d8c833b76e382608cb59e9", + "000000000000000019d43247356b848a7ef8b1c786d8c833b76e382608cb59e9", 1438882362326364789097016808333128944459434864174551793664 - ], + ], [ - "00000000000000003711b624fbde8c77d4c7e25334cfa8bc176b7248ca67b24b", + "00000000000000003711b624fbde8c77d4c7e25334cfa8bc176b7248ca67b24b", 1366448002777625511026173062127977611952455397852592472064 - ], + ], [ - "0000000000000000092c1f996e0b6d07fd0e73dfe6409a5c2adc1206e997c3a2", + "0000000000000000092c1f996e0b6d07fd0e73dfe6409a5c2adc1206e997c3a2", 1130631509982695295834811811892052032638591596239280668672 - ], + ], [ - "000000000000000020ce180d66df9d3c28aee9fcec7896071ec67091a9753283", + "000000000000000020ce180d66df9d3c28aee9fcec7896071ec67091a9753283", 982897592923314645728937741958820396011314229953349812224 - ], + ], [ - "000000000000000018d37d53ae02e13634eefb8d9246253e99c1bdf65ac293ea", + "000000000000000018d37d53ae02e13634eefb8d9246253e99c1bdf65ac293ea", 903780639904017349860452775965599807564731663176966340608 - ], + ], [ - "00000000000000001607d1a21507dea1c0e5f398daf94d35fb7e0a3238f96a0f", + "00000000000000001607d1a21507dea1c0e5f398daf94d35fb7e0a3238f96a0f", 777796486219054632155478957346406689849105796561635377152 - ], + ], [ - "00000000000000001acae244523061f650ddab9c3271d13c0cd86071ae6e8a5f", + "00000000000000001acae244523061f650ddab9c3271d13c0cd86071ae6e8a5f", 770217816864616291160628694313702426464491250746461782016 - ], + ], [ - "0000000000000000104430189dba1219b0e3dd90824e8c2271609aca5b71250f", + "0000000000000000104430189dba1219b0e3dd90824e8c2271609aca5b71250f", 749174812297985386116525053725808178560617045558724395008 - ], + ], [ - "00000000000000001aa260733b6d8f8faa2092af35e55973278bb17f8eaeca6b", + "00000000000000001aa260733b6d8f8faa2092af35e55973278bb17f8eaeca6b", 680733321990486529407107157001552378184394215934016880640 - ], + ], [ - "000000000000000009925ad5866a9cb3a1d83d9399137bccc7b5470b38b1db2b", + "000000000000000009925ad5866a9cb3a1d83d9399137bccc7b5470b38b1db2b", 668970595596618687654683311252875969389523722950049529856 - ], + ], [ - "00000000000000001133acacb92e43e24af63a487923361a4a98c87a5550dffe", + "00000000000000001133acacb92e43e24af63a487923361a4a98c87a5550dffe", 673862533877092685902494685124943911912916060357898797056 - ], + ], [ - "000000000000000018c66b4a76ca69204e24ee069da9368c7a9883adb36c24af", + "000000000000000018c66b4a76ca69204e24ee069da9368c7a9883adb36c24af", 683252062220249508849116041812776958610205092831121375232 - ], + ], [ - "000000000000000010b13aed220b96c35ccd5f07125b51308db976eefcd718f9", + "000000000000000010b13aed220b96c35ccd5f07125b51308db976eefcd718f9", 663358803453687177159928221638562617962497973903752691712 - ], + ], [ - "0000000000000000031b14ece1cfda0e23774e473cd2676834f73155e4f46a2b", + "0000000000000000031b14ece1cfda0e23774e473cd2676834f73155e4f46a2b", 613111582105360026820898034285227810088764320248934432768 - ], + ], [ - "000000000000000010bfa427c8d305d861ab5ee4776d87d6d911f5fb3045c754", + "000000000000000010bfa427c8d305d861ab5ee4776d87d6d911f5fb3045c754", 653202279051259096361833571150520065936493508031976308736 - ], + ], [ - "000000000000000005d1e9e192a43a19e2fbd933ffb27df2623187ad5ce10adc", + "000000000000000005d1e9e192a43a19e2fbd933ffb27df2623187ad5ce10adc", 606439838822957553646521558653356639834299145437709336576 - ], + ], [ - "00000000000000000f9e30784bd647e91f6923263a674c9c5c18084fe79a41f8", + "00000000000000000f9e30784bd647e91f6923263a674c9c5c18084fe79a41f8", 577485176368838834686684127480472050622611986764206702592 - ], + ], [ - "00000000000000000036d3e1c36e4b959a3e4ad6376ce9ae65961e60350c86e8", + "00000000000000000036d3e1c36e4b959a3e4ad6376ce9ae65961e60350c86e8", 568436119447114618883887501211268589217582000336195813376 - ], + ], [ - "00000000000000000b3ec9df7aebc319bb12491ba651337f9b3541e78446eca8", + "00000000000000000b3ec9df7aebc319bb12491ba651337f9b3541e78446eca8", 577075114085443079269506210404847846798089003835028668416 - ], + ], [ - "000000000000000012d24ce222e3c81d4c148f2bce88f752c0dba184c3bc6844", + "000000000000000012d24ce222e3c81d4c148f2bce88f752c0dba184c3bc6844", 545227566982404669720599751103563308707559049533419683840 - ], + ], [ - "000000000000000000c4ccbdd98c267bd16bda12b63b648c47af3ac51c1cc574", + "000000000000000000c4ccbdd98c267bd16bda12b63b648c47af3ac51c1cc574", 566251116039239425785056264238964437451875594947144974336 - ], + ], [ - "00000000000000000056bfec1dca8e82710f411af64b1d3b04a2d2364a81993f", + "00000000000000000056bfec1dca8e82710f411af64b1d3b04a2d2364a81993f", 565860883410058976058672534759150528155363303710710038528 - ], + ], [ - "00000000000000001275d1cadce690546f74f77f6d4a6190e2137a8a819946f6", + "00000000000000001275d1cadce690546f74f77f6d4a6190e2137a8a819946f6", 552364745922238091561919045022000637317595931246011088896 - ], + ], [ - "000000000000000003816ae80c6413b84cbee2f639ba497ab5872ec9711eb256", + "000000000000000003816ae80c6413b84cbee2f639ba497ab5872ec9711eb256", 566500670366816952120145379831520408210047884740723212288 - ], + ], [ - "00000000000000000d92953224570f521b09553194da1ca3c4b31a09a238f4f6", + "00000000000000000d92953224570f521b09553194da1ca3c4b31a09a238f4f6", 542528489142608155505707877213460200687386787807972294656 - ], + ], [ - "000000000000000006721943f23cfacf20c17c2ad6ea4e902af36b01f92e3c06", + "000000000000000006721943f23cfacf20c17c2ad6ea4e902af36b01f92e3c06", 545717322027080804612101478705745866012577831152301113344 - ], + ], [ - "0000000000000000031d9af2fe38cc02410361fb213181fdb667c74e210d54c4", + "0000000000000000031d9af2fe38cc02410361fb213181fdb667c74e210d54c4", 527827980769521817826567786138322798799309668948178370560 - ], + ], [ - "0000000000000000142e8a13ef6994961655c8e86aece3f0abebd2ee05473e75", + "0000000000000000142e8a13ef6994961655c8e86aece3f0abebd2ee05473e75", 515692606534173891771672037645739723025219384908133171200 - ], + ], [ - "00000000000000000c7a8db37a746d6637ef6a6eab28735608fd715ee2f394e7", + "00000000000000000c7a8db37a746d6637ef6a6eab28735608fd715ee2f394e7", 511567664312971151375333957573881285830542480898837708800 - ], + ], [ - "000000000000000007854877c66c71a49af40d20f2d6f817becfe4d66d5e5a81", + "000000000000000007854877c66c71a49af40d20f2d6f817becfe4d66d5e5a81", 496889230460615059653870414954457230681194245244172894208 - ], + ], [ - "000000000000000005ce1d2d10aeb9def4d38233e859d98a4a168ea3fa36687a", + "000000000000000005ce1d2d10aeb9def4d38233e859d98a4a168ea3fa36687a", 473325989086544548323169648982069700877697035484407005184 - ], + ], [ - "000000000000000007c71decfe74855ad99dc2aa4a2e713165db5a8d6da5f32a", + "000000000000000007c71decfe74855ad99dc2aa4a2e713165db5a8d6da5f32a", 454358737757395076722955683517864397151243915416267915264 - ], + ], [ - "000000000000000008ce4f34161be6760569877c685e37ebebce3546ea42a767", + "000000000000000008ce4f34161be6760569877c685e37ebebce3546ea42a767", 443316987659242217350916733941384923365365929826941140992 - ], + ], [ - "0000000000000000086233f4843682eb47bacb58930a5577fbfd5c9ebd57ddf9", + "0000000000000000086233f4843682eb47bacb58930a5577fbfd5c9ebd57ddf9", 442802913227320896234856097023585967110900073490544590848 - ], + ], [ - "000000000000000010a904eee4fc763c6b88d378884f368fd652f63c1af71580", + "000000000000000010a904eee4fc763c6b88d378884f368fd652f63c1af71580", 433057199397126884276233483897801969646324654385408245760 - ], + ], [ - "00000000000000000c114754749d622d4fa2f78c84d7147c345b2b99a8e83d2e", + "00000000000000000c114754749d622d4fa2f78c84d7147c345b2b99a8e83d2e", 409419129139225030716120689261979366152221060879441985536 - ], + ], [ - "000000000000000000a5039e32cc9a89aeffbde1391e8bc9ae9724127904f01d", + "000000000000000000a5039e32cc9a89aeffbde1391e8bc9ae9724127904f01d", 370716507988397359530778284103407727265240291588416995328 - ], + ], [ - "000000000000000003b0b73d9b3259c318cca48a6335b5d64545583f7f3773fa", + "000000000000000003b0b73d9b3259c318cca48a6335b5d64545583f7f3773fa", 340818253309165415058055171484606858815006633875327680512 - ], + ], [ - "00000000000000000198bcc5bd65fd0ccd1c7e3b49e0170ea80296cbfee05042", + "00000000000000000198bcc5bd65fd0ccd1c7e3b49e0170ea80296cbfee05042", 288495652867775987986282369150900282132304927019642126336 - ], + ], [ - "00000000000000000a60f379d3dc1413491f360809a97cbb02c81442c613dce7", + "00000000000000000a60f379d3dc1413491f360809a97cbb02c81442c613dce7", 259524902203633530447121351815377152077137395840706412544 - ], + ], [ - "0000000000000000038973a5f8ba8cdc7e371dcc8f4b24337ef695f24b962907", + "0000000000000000038973a5f8ba8cdc7e371dcc8f4b24337ef695f24b962907", 237834253647442358407456603145452341381064939329604812800 - ], + ], [ - "000000000000000004b8ec471974913d052a3af7dc2a8c6f01c2ac2f3d1f7b19", + "000000000000000004b8ec471974913d052a3af7dc2a8c6f01c2ac2f3d1f7b19", 224600391397450328424792273873642383828872941895338164224 - ], + ], [ - "0000000000000000075d572eef1c4210adc7abf4e40986d7f0a80003853bfec4", + "0000000000000000075d572eef1c4210adc7abf4e40986d7f0a80003853bfec4", 187067719845325692996306936867878122094522982476155977728 - ], + ], [ - "0000000000000000074f9edbfc07648dc74392ba8248f0983ffea63431b3bc20", + "0000000000000000074f9edbfc07648dc74392ba8248f0983ffea63431b3bc20", 164898540577033087399552264895286015147022701908103004160 - ], + ], [ - "000000000000000003c4a4d9c62b3a7f4893afe14eef8a6a377229d23ad4b1ea", + "000000000000000003c4a4d9c62b3a7f4893afe14eef8a6a377229d23ad4b1ea", 170169861298531990750482624090969781281789404909188153344 - ], + ], [ - "00000000000000000404b6939e6c35a5448386e5d58f318c82ce2fefb7d73e47", + "00000000000000000404b6939e6c35a5448386e5d58f318c82ce2fefb7d73e47", 162900609378736249874251099581569547607832255884553093120 - ], + ], [ - "0000000000000000034656c96781091b5fbc799c881ea85b41cba0b88128eff7", + "0000000000000000034656c96781091b5fbc799c881ea85b41cba0b88128eff7", 161578008857017275969393492955354620126364423170461532160 - ], + ], [ - "0000000000000000045645e2acd740a88d2b3a09369e9f0f80d5376e4b6c5189", + "0000000000000000045645e2acd740a88d2b3a09369e9f0f80d5376e4b6c5189", 150883090635422687830679296233896712896447026244773478400 - ], + ], [ - "00000000000000000381e6a138308c6547d6fe3eb3437250ffefdebbf71eefd1", + "00000000000000000381e6a138308c6547d6fe3eb3437250ffefdebbf71eefd1", 150899178845446426410002882396535253739927398750206558208 - ], + ], [ - "0000000000000000012100ddbb2102e65fb1ebbf104ead754a4110abffc4b8bc", + "0000000000000000012100ddbb2102e65fb1ebbf104ead754a4110abffc4b8bc", 138784382553152119468195441786396823230753870240366460928 - ], + ], [ - "0000000000000000046f56e59b9b1293b5e7c1587aa6d29c4f3f79b98cf22ee6", + "0000000000000000046f56e59b9b1293b5e7c1587aa6d29c4f3f79b98cf22ee6", 135262935280049154152065372885142255350817451144176992256 - ], + ], [ - "000000000000000001bd1c291e91f4476f93454d4542d2ed7e44fc86902c93bb", + "000000000000000001bd1c291e91f4476f93454d4542d2ed7e44fc86902c93bb", 137505556928474480767543871928291413858290772017802117120 - ], + ], [ - "000000000000000001c37a483375ff6fd6ed7c5b79d80167b027a8fdb0721dcd", + "000000000000000001c37a483375ff6fd6ed7c5b79d80167b027a8fdb0721dcd", 128713911367130082233924624261304605948946745676720504832 - ], + ], [ - "0000000000000000051804b4c2da5298c4573386bf1d4242bf0e26a49ec32e42", + "0000000000000000051804b4c2da5298c4573386bf1d4242bf0e26a49ec32e42", 126333978716874242627475052620752087219210710628817698816 - ], + ], [ - "0000000000000000034bff7888f1f7294311f0199322f77c1457018c875bd9e1", + "0000000000000000034bff7888f1f7294311f0199322f77c1457018c875bd9e1", 126278605342839049377710151409810132688161986656629424128 - ], + ], [ - "00000000000000000506b43c9283ccbc40f583e0c734e4a8af2ce6a4262c6221", + "00000000000000000506b43c9283ccbc40f583e0c734e4a8af2ce6a4262c6221", 133533639774706835230353390473157702360903922769486413824 - ], + ], [ - "000000000000000003937068e19a0750a33978050f019d2b60f430e3da707db9", + "000000000000000003937068e19a0750a33978050f019d2b60f430e3da707db9", 124022888639743237872084547350559836284832548627419234304 - ], + ], [ - "000000000000000002e2f6ec3c9eb965aa706c788da7dede201b6b4b8fae3971", + "000000000000000002e2f6ec3c9eb965aa706c788da7dede201b6b4b8fae3971", 122123731568103772089607259872577666017242529148853813248 - ], + ], [ - "000000000000000000b3076636b13562bb4315f895bcb324e0c962763c2196b1", + "000000000000000000b3076636b13562bb4315f895bcb324e0c962763c2196b1", 119378259820331825692479928211144812308894309500762193920 - ], + ], [ - "00000000000000000025b8961d1d0cfba33b0205ec10b3ce541618e352b0bbd5", + "00000000000000000025b8961d1d0cfba33b0205ec10b3ce541618e352b0bbd5", 111759931157462873316041289986819959868258380300102402048 - ], + ], [ - "00000000000000000421d58b78b9f063a4b20e181d55c9c79082f9e4b8b30925", + "00000000000000000421d58b78b9f063a4b20e181d55c9c79082f9e4b8b30925", 104283029085035157753191385936387396702868516379761311744 - ], + ], [ - "0000000000000000027fd968d41741f31c73c4a3b304472da0165245278e2ea3", + "0000000000000000027fd968d41741f31c73c4a3b304472da0165245278e2ea3", 106299667504289830835845558415962632664710558339861315584 - ], + ], [ - "00000000000000000364a23184b8a2c009d13172094421c22e4d9bc85dcf90a5", + "00000000000000000364a23184b8a2c009d13172094421c22e4d9bc85dcf90a5", 105881374043672627773432318187360570734220873198601240576 - ], + ], [ - "0000000000000000042a2ed4a504424060407825d774a54f2e148fa769ee72ff", + "0000000000000000042a2ed4a504424060407825d774a54f2e148fa769ee72ff", 95668727978371040303278646201741713440261619517174579200 - ], + ], [ - "0000000000000000025f769f13f2806fed19d9948b1a7ef19048177789afc5d3", + "0000000000000000025f769f13f2806fed19d9948b1a7ef19048177789afc5d3", 94012390634764280055243391736606357298689315295029362688 - ], + ], [ - "000000000000000000b3ff31d54e9e83515ee18360c7dc59e30697d083c745ff", + "000000000000000000b3ff31d54e9e83515ee18360c7dc59e30697d083c745ff", 86923102180582917240747796162767475850640519180006195200 - ], + ], [ - "0000000000000000021ecdcb2368ce66c23efd8bd8ab6a88a8bb70571c6e67f0", + "0000000000000000021ecdcb2368ce66c23efd8bd8ab6a88a8bb70571c6e67f0", 84861566431029438820446406485131195674434646972185968640 - ], + ], [ - "000000000000000001972cb33b862b27c1dc3f3a723f7d1cfd69aebe0409126c", + "000000000000000001972cb33b862b27c1dc3f3a723f7d1cfd69aebe0409126c", 80022382513656536844370512820784980102919810105407963136 - ], + ], [ - "000000000000000000cb26d2b1018d80670ccc41d89c7da92175bd6b00f27a3e", + "000000000000000000cb26d2b1018d80670ccc41d89c7da92175bd6b00f27a3e", 68605739707508652902977299640495787127103841947617329152 - ], + ], [ - "00000000000000000276deb4022f66cacd929c690cd6b4f7e740836b614b21f4", + "00000000000000000276deb4022f66cacd929c690cd6b4f7e740836b614b21f4", 63859343606086615291372321518809062931940920926127783936 - ], + ], [ - "000000000000000000587912ced677698c86eec8b1d70144dccb1c6b0bad0f17", + "000000000000000000587912ced677698c86eec8b1d70144dccb1c6b0bad0f17", 61163258921643354765656928775243357859392914550528409600 - ], + ], [ - "0000000000000000009f989a246ac4221ebdced8ccebae9b8d5c83b69bb5e7c8", + "0000000000000000009f989a246ac4221ebdced8ccebae9b8d5c83b69bb5e7c8", 58509826700983959310706392369835644790490546910263246848 - ], + ], [ - "000000000000000000038bed8b89c4e82c13076dd64dc5f7a349c39d3921d607", + "000000000000000000038bed8b89c4e82c13076dd64dc5f7a349c39d3921d607", 56672777602924507578641088682504585686103825941044133888 - ], + ], [ - "00000000000000000122f47d580700a3a5b4b6cb46669a36e4fa974c720ab6cd", + "00000000000000000122f47d580700a3a5b4b6cb46669a36e4fa974c720ab6cd", 53958359841942568206719748916397287559357255547625668608 - ], + ], [ - "00000000000000000172ad9ea56a90bdfed0f364a902500e9ff4d74f000ced99", + "00000000000000000172ad9ea56a90bdfed0f364a902500e9ff4d74f000ced99", 51764751112426770751506128647798102319231116027761786880 - ], + ], [ - "00000000000000000201d7429db233c7055e9699c5bfb57b167ca8d0c710dc71", + "00000000000000000201d7429db233c7055e9699c5bfb57b167ca8d0c710dc71", 51649140486907347007064544362790913467244253139882213376 - ], + ], [ - "000000000000000000c0549b2a8adbefbf6c909f61fdc4d6087c44a549cf8201", + "000000000000000000c0549b2a8adbefbf6c909f61fdc4d6087c44a549cf8201", 48144529712666433692552181910809237167694270386587828224 - ], + ], [ - "0000000000000000015b6789cdc5dc13766f58b38f16d5b35bf79ce4b040f7fd", + "0000000000000000015b6789cdc5dc13766f58b38f16d5b35bf79ce4b040f7fd", 45240046586752885057924289339576851866807485277820420096 - ], + ], [ - "0000000000000000013a31b29f845d97465bff53f901027f8ab4b1a2f59118a8", + "0000000000000000013a31b29f845d97465bff53f901027f8ab4b1a2f59118a8", 39718797393257298660757754408019939605415460564426031104 - ], + ], [ - "00000000000000000088cdeaa7389a7de9f09e3a28b3647630fea3bd1b107134", + "00000000000000000088cdeaa7389a7de9f09e3a28b3647630fea3bd1b107134", 37880625861940376795251270290737354395669643839013912576 - ], + ], [ - "000000000000000001389446206ebcd378c32cd00b4920a8a1ba7b540ca7d699", + "000000000000000001389446206ebcd378c32cd00b4920a8a1ba7b540ca7d699", 38043004539854389433075372490391464304285496568268718080 - ], + ], [ - "000000000000000000f41e2b7f056b6edef47477d0d0f5833d5d4a047151f2dc", + "000000000000000000f41e2b7f056b6edef47477d0d0f5833d5d4a047151f2dc", 33509870757351677175294676059494700127350769223450230784 - ], + ], [ - "0000000000000000010e0373719b7538e713e47d8d7189826dce4264d85a79b8", + "0000000000000000010e0373719b7538e713e47d8d7189826dce4264d85a79b8", 31340207270661909233492904963194738468218672502370467840 - ], + ], [ - "00000000000000000053e2d10bd703ad5b7787614965711d6170b69b133aa366", + "00000000000000000053e2d10bd703ad5b7787614965711d6170b69b133aa366", 29201223626342991605750065618903157022235193117232857088 - ], + ], [ - "000000000000000000cbeff0b533f8e1189cf09dfbebf57a8ebe349362811b80", + "000000000000000000cbeff0b533f8e1189cf09dfbebf57a8ebe349362811b80", 30353962581764818649842367179120467226026534727449575424 - ], + ], [ - "000000000000000000d0ad638ad61e7c4c3113618b8b26b2044347c00c042278", + "000000000000000000d0ad638ad61e7c4c3113618b8b26b2044347c00c042278", 29217311836366730185073651781541697865715565622665936896 - ], + ], [ - "000000000000000000a7bda943639876a2d7a8caf4cac45678fb237d59c28ba1", + "000000000000000000a7bda943639876a2d7a8caf4cac45678fb237d59c28ba1", 24433127148609864747615599184820261456796420809345204224 - ], + ], [ - "000000000000000000fb6c6a307c8363e923873499ba6299597769c10a438e61", + "000000000000000000fb6c6a307c8363e923873499ba6299597769c10a438e61", 23988269434232535193761088780698748366141469438183997440 - ], + ], [ - "0000000000000000006f408147ffbcaa0fb1dcf1f199c527ffdaf159d86e5cd9", + "0000000000000000006f408147ffbcaa0fb1dcf1f199c527ffdaf159d86e5cd9", 22526487188587264742197108840494583820145762956159746048 - ], + ], [ - "000000000000000000e3be3cf7343d7792c0d47d3c39ddb9ceaf19961e9eeab4", + "000000000000000000e3be3cf7343d7792c0d47d3c39ddb9ceaf19961e9eeab4", 18556440756915402760741928101946749165024073301499052032 - ], + ], [ - "000000000000000000b3fb09d6def197657e20f9c1d5e9680cfcac1e1f9aa269", + "000000000000000000b3fb09d6def197657e20f9c1d5e9680cfcac1e1f9aa269", 19758940920085072387393228723348383373068660102939017216 - ], + ], [ - "000000000000000000bfe71f044145e1b42fdfb3a523ee2a215e80fa6afc2a98", + "000000000000000000bfe71f044145e1b42fdfb3a523ee2a215e80fa6afc2a98", 20014481558369106100835306608979160026489460596213284864 - ], + ], [ - "000000000000000000cee3bff56ee49c0f96d1cbd17fa17dc6f84b3f48aed765", + "000000000000000000cee3bff56ee49c0f96d1cbd17fa17dc6f84b3f48aed765", 16946123176864917983795071264823963343174695083267063808 - ], + ], [ - "00000000000000000089ef13654974b8896b0b0909dd9ae8e350b8a8a7807ce3", + "00000000000000000089ef13654974b8896b0b0909dd9ae8e350b8a8a7807ce3", 14392961660539521116256653268419249019684881662910398464 - ], + ], [ - "0000000000000000003105a067417c318dab31e25ae1583fa2b27be226945fdd", + "0000000000000000003105a067417c318dab31e25ae1583fa2b27be226945fdd", 13960450711994363030255127593764523087979983609872252928 - ], + ], [ - "000000000000000000720da39f66f29337b9a29223e1ce05fd5ee57bb72a9223", + "000000000000000000720da39f66f29337b9a29223e1ce05fd5ee57bb72a9223", 12101157559014734955774763823279522156034099347349045248 - ], + ], [ - "0000000000000000006a8957cbd52c2038861514f106f7f9f76392d5cb83fd4c", + "0000000000000000006a8957cbd52c2038861514f106f7f9f76392d5cb83fd4c", 10356793971791534424976101420669664288187918308140384256 - ], + ], [ - "0000000000000000006b68e55432541794388c94fe9e805652038e7b3cac0681", + "0000000000000000006b68e55432541794388c94fe9e805652038e7b3cac0681", 9378292318569022964986206758839123913433917663832178688 - ], + ], [ - "00000000000000000001c9deea9f0302eadb1250df1ad53da802dfb40d47face", + "00000000000000000001c9deea9f0302eadb1250df1ad53da802dfb40d47face", 8964447668935855171055978546867850348456065181232922624 - ], + ], [ - "00000000000000000013aaa8778111530a626a3fe57e4e6f4a878c92669b04d1", + "00000000000000000013aaa8778111530a626a3fe57e4e6f4a878c92669b04d1", 8192878571041388924351625416816775770172128369752145920 - ], + ], [ - "0000000000000000002f67aa98789b98304a32e54bffbb34c8693eb0acac4c30", + "0000000000000000002f67aa98789b98304a32e54bffbb34c8693eb0acac4c30", 7786052052270684126234611299412205796254663675224260608 - ], + ], [ - "0000000000000000002e5f072398ee27b25b6cdcf69051bcdbbece417093c979", + "0000000000000000002e5f072398ee27b25b6cdcf69051bcdbbece417093c979", 7678459224733657715202292429397298472913633233275453440 - ], + ], [ - "00000000000000000028d7447c20ade2053bbaf49e8a16eb5fb1bc74335d0d18", + "00000000000000000028d7447c20ade2053bbaf49e8a16eb5fb1bc74335d0d18", 7021961458254440109762706424650140438182306270565892096 - ], + ], [ - "00000000000000000042d89446b9043387be2d4c09aa9e9524176c5754616510", + "00000000000000000042d89446b9043387be2d4c09aa9e9524176c5754616510", 6702918573828378664524678433037841287557455508299317248 - ], + ], [ - "00000000000000000018ec4d369bab2c13174834a02138decea7c85685d46bd6", + "00000000000000000018ec4d369bab2c13174834a02138decea7c85685d46bd6", 6505870154073602347674948421782035713149324747260035072 - ], + ], [ - "0000000000000000000d4a6c2237c6c46b963b17f60d9c850c4915518deb6678", + "0000000000000000000d4a6c2237c6c46b963b17f60d9c850c4915518deb6678", 6259542822111302646229226565336702507884435252736688128 - ], + ], [ - "00000000000000000031adb986da21237ce06b57ae5390b7f0f890ab8e21b66a", + "00000000000000000031adb986da21237ce06b57ae5390b7f0f890ab8e21b66a", 5456617206587901877414813377199700077413780408546361344 - ], + ], [ - "000000000000000000031df41201cd3789559333cd9529f99834a805014c9b13", + "000000000000000000031df41201cd3789559333cd9529f99834a805014c9b13", 5309609141393698345581459330931267317315649121846034432 - ], + ], [ - "00000000000000000020c68bfc8de14bc9dd2d6cf45161a67e0c6455cf28cfd8", + "00000000000000000020c68bfc8de14bc9dd2d6cf45161a67e0c6455cf28cfd8", 5026314587016750785722693470327208449351582469580652544 - ], + ], [ - "00000000000000000009dce52e227d46a6bdf38a8c1f2e88c6044893289c2bf0", + "00000000000000000009dce52e227d46a6bdf38a8c1f2e88c6044893289c2bf0", 5205879062684137510961952799929229129995569309608312832 - ], + ], [ - "0000000000000000002eca92f4e44dcf144115851689ace0ff4ce271792f16fe", + "0000000000000000002eca92f4e44dcf144115851689ace0ff4ce271792f16fe", 4531442825108320403104334767545311437480985430866264064 - ], + ], [ - "00000000000000000000943de85f4495f053ff55f27d135edc61c27990c2eec5", + "00000000000000000000943de85f4495f053ff55f27d135edc61c27990c2eec5", 4219470685603665866184576203153693664105230070242607104 - ], + ], [ - "0000000000000000001d9d48d93793aaa85b5f6d17c176d4ef905c7e7112b1cf", + "0000000000000000001d9d48d93793aaa85b5f6d17c176d4ef905c7e7112b1cf", 4007526641161212986792514236082843733160766044725313536 - ], + ], [ - "0000000000000000001877e616b546d1ba5cf9e8b8edd9eba480a4fbb9f02bce", + "0000000000000000001877e616b546d1ba5cf9e8b8edd9eba480a4fbb9f02bce", 3840827764407250199942201944063224491938810378873470976 - ], + ], [ - "00000000000000000025eb2c783f2f29d68ab4260f4b0248450c0038debc7ba4", + "00000000000000000025eb2c783f2f29d68ab4260f4b0248450c0038debc7ba4", 3769176185135465353474348091454476000617158630021529600 - ], + ], [ - "0000000000000000000c61b8a7779dcc46e88ca343b9a3fcc6763917fe3b87e2", + "0000000000000000000c61b8a7779dcc46e88ca343b9a3fcc6763917fe3b87e2", 3616317728887026217259424694800679959591344645351669760 + ], + [ + "00000000000000000003dba9fedba6a0b92b640167eeda0d41485a3c85ac4ac6", + 3753318892370425056811838111019504329853891761930240000 + ], + [ + "0000000000000000001ac75bed7eb6169255893f99de28f24e3e0e57b6f7db7b", + 3752507758961706405692235065937346792777982719368888320 + ], + [ + "0000000000000000000e5796e9c5cdc8a8a2de84fd17287d7dfe89074de31766", + 4052052750044136275098507698196378011637603685579620352 + ], + [ + "00000000000000000015fe695e8d2e5ed3a7de81d3818ef43a444e1ee7b3ace2", + 4774638159061819979596346127394133648234752261950013440 + ], + [ + "00000000000000000015a08d0a60237487070fe0d956d5fb5fd9d21ad6d7b2d3", + 5279534360700703025330663904443631645337169341976674304 + ], + [ + "00000000000000000008f4f64baaa9b28d4476f2a000c459df492d5664320b12", + 4798269179035823348880781507454323228379569035237392384 + ], + [ + "00000000000000000028a69d9498c46b2b073752133e3e9e585965e7dab55065", + 4581847093576588582947343450056030606262879232408420352 + ], + [ + "00000000000000000014dbca1d9ea7256a3993253c033a50d8b3064a2cbd056b", + 4636475101776743072223960781733299832971578678999777280 + ], + [ + "00000000000000000019046cf62aa17f6e526636c71c09161c8e730b64d755ae", + 4447653474738502407900799312400854215681091162244907008 + ], + [ + "00000000000000000017e5c36734296b27065045f181e028c0d91cebb336d50c", + 4440088742263677654396177039706714734771352055402463232 + ], + [ + "0000000000000000002296c06935b34f3ed946d98781ff471a99101796e8611b", + 4442250303185290059812200289574302117357423179633524736 + ], + [ + "0000000000000000001ccf7aa37a7f07e4d709eef9c6c4abd0b808686b14c314", + 4226119056551884143559484765457720035561644907380604928 + ], + [ + "0000000000000000000de3e7a7711130dbac9fb0a14e5ad6ab72d080182f3321", + 4217024131862773934699503234743726606330326039165665280 + ], + [ + "0000000000000000000e6829c1245de98ce5a35c177a75f67e9c1678cb6e24aa", + 4243570847603252455305754966045185171099356397876281344 + ], + [ + "00000000000000000001b2505c11119fcf29be733ec379f686518bf1090a522a", + 4022508494445492072607020209303018350395259009223360512 + ], + [ + "0000000000000000000a4adf6c5192128535d4dcb56cfb5753755f8d392b26bf", + 4021030916290150529756716283937142188262386861422411776 + ], + [ + "0000000000000000000485ab94f5ea60203aacfc9740b3e42700d7e7012f76d7", + 3614033401827878015998272335407144409231622422786998272 + ], + [ + "0000000000000000000cbc6dfb3f2afbd6ed1427e30ed1f3167898ac4aa4c673", + 3638558860803927897868648370584956354584468626790678528 ] -] \ No newline at end of file +] + diff --git a/eclair-core/src/main/resources/electrum/checkpoints_testnet.json b/eclair-core/src/main/resources/electrum/checkpoints_testnet.json index 0597713033..fa2eff4080 100644 --- a/eclair-core/src/main/resources/electrum/checkpoints_testnet.json +++ b/eclair-core/src/main/resources/electrum/checkpoints_testnet.json @@ -1,2858 +1,3107 @@ [ [ - "00000000864b744c5025331036aa4a16e9ed1cbb362908c625272150fa059b29", + "00000000864b744c5025331036aa4a16e9ed1cbb362908c625272150fa059b29", 0 - ], + ], [ - "000000002e9ccffc999166ccf8d72129e1b2e9c754f6c90ad2f77cab0d9fb4c7", + "000000002e9ccffc999166ccf8d72129e1b2e9c754f6c90ad2f77cab0d9fb4c7", 0 - ], + ], [ - "0000000009b9f0436a9c733e2c9a9d9c8fe3475d383bdc1beb7bfa995f90be70", + "0000000009b9f0436a9c733e2c9a9d9c8fe3475d383bdc1beb7bfa995f90be70", 0 - ], + ], [ - "000000000a9c9c79f246042b9e2819822287f2be7cd6487aecf7afab6a88bed5", + "000000000a9c9c79f246042b9e2819822287f2be7cd6487aecf7afab6a88bed5", 0 - ], + ], [ - "000000003a7002e1247b0008cba36cd46f57cd7ce56ac9d9dc5644265064df09", + "000000003a7002e1247b0008cba36cd46f57cd7ce56ac9d9dc5644265064df09", 0 - ], + ], [ - "00000000061e01e82afff6e7aaea4eb841b78cc0eed3af11f6706b14471fa9c8", + "00000000061e01e82afff6e7aaea4eb841b78cc0eed3af11f6706b14471fa9c8", 0 - ], + ], [ - "000000003911e011ae2459e44d4581ac69ba703fb26e1421529bd326c538f12d", + "000000003911e011ae2459e44d4581ac69ba703fb26e1421529bd326c538f12d", 0 - ], + ], [ - "000000000a5984d6c73396fe40de392935f5fc2a8e48eedf38034ce0a3178a60", + "000000000a5984d6c73396fe40de392935f5fc2a8e48eedf38034ce0a3178a60", 0 - ], + ], [ - "000000000786bdc642fa54c0a791d58b732ed5676516fffaeca04492be97c243", + "000000000786bdc642fa54c0a791d58b732ed5676516fffaeca04492be97c243", 0 - ], + ], [ - "000000001359c49f9618f3ee69afbd1b3196f1832acc47557d42256fcc6b7f48", + "000000001359c49f9618f3ee69afbd1b3196f1832acc47557d42256fcc6b7f48", 0 - ], + ], [ - "00000000270dde98d582af35dff5aed02087dad8529dc5c808c67573d6dabaf4", + "00000000270dde98d582af35dff5aed02087dad8529dc5c808c67573d6dabaf4", 0 - ], + ], [ - "00000000425c160908c215c4adf998771a2d1c472051bc58320696f3a5eb0644", + "00000000425c160908c215c4adf998771a2d1c472051bc58320696f3a5eb0644", 0 - ], + ], [ - "0000000006a5976471986377805d4a148d8822bb7f458138c83f167d197817c9", + "0000000006a5976471986377805d4a148d8822bb7f458138c83f167d197817c9", 0 - ], + ], [ - "000000000318394ea17038ef369f3cccc79b3d7dfda957af6c8cd4a471ffa814", + "000000000318394ea17038ef369f3cccc79b3d7dfda957af6c8cd4a471ffa814", 0 - ], + ], [ - "000000000ad4f9d0b8e86871478cc849f7bc42fb108ebec50e4a795afc284926", + "000000000ad4f9d0b8e86871478cc849f7bc42fb108ebec50e4a795afc284926", 0 - ], + ], [ - "000000000207e63e68f2a7a4c067135883d726fd65e3620142fb9bdf50cce1f6", + "000000000207e63e68f2a7a4c067135883d726fd65e3620142fb9bdf50cce1f6", 0 - ], + ], [ - "00000000003b426d2c12ee66b2eedb4dcc05d5e158685b222240d31e43687762", + "00000000003b426d2c12ee66b2eedb4dcc05d5e158685b222240d31e43687762", 0 - ], + ], [ - "00000000017cf6ee86e3d483f9a978ded72be1fa5af37d287a71c5dfb87cdd83", + "00000000017cf6ee86e3d483f9a978ded72be1fa5af37d287a71c5dfb87cdd83", 0 - ], + ], [ - "00000000004b1d9fe16fc0c72cfa0395c98a3e460cd2affb8640e28bca295a4a", + "00000000004b1d9fe16fc0c72cfa0395c98a3e460cd2affb8640e28bca295a4a", 0 - ], + ], [ - "0000000046d191b09f7726e4f8bfaffed6c30734afbf1f95e6bddbe0b07d9e88", + "0000000046d191b09f7726e4f8bfaffed6c30734afbf1f95e6bddbe0b07d9e88", 0 - ], + ], [ - "0000000082cec8200e9ea055c2991bf74560eb7e7140691ea53e7828dbdc9553", + "0000000082cec8200e9ea055c2991bf74560eb7e7140691ea53e7828dbdc9553", 0 - ], + ], [ - "000000003775b96d6b362d4804afe2d9c3cf3cbb46a45c3ccc377c94e83edd23", + "000000003775b96d6b362d4804afe2d9c3cf3cbb46a45c3ccc377c94e83edd23", 0 - ], + ], [ - "00000000037835a92404acb2f18768a49d4f93685ead30aad6bb3b073f411e02", + "00000000037835a92404acb2f18768a49d4f93685ead30aad6bb3b073f411e02", 0 - ], + ], [ - "0000000006cf75d17706d1f62e6b08e6ba5facfde38a8920b7d808a6b6781ff2", + "0000000006cf75d17706d1f62e6b08e6ba5facfde38a8920b7d808a6b6781ff2", 0 - ], + ], [ - "0000000003dff257cdae43703fcd0ca91fda0970f5fc04258b4608fb1942a6f6", + "0000000003dff257cdae43703fcd0ca91fda0970f5fc04258b4608fb1942a6f6", 0 - ], + ], [ - "0000000000532d97d18867658e08c789f627535652382147e33bf8626d4131bc", + "0000000000532d97d18867658e08c789f627535652382147e33bf8626d4131bc", 0 - ], + ], [ - "000000000266dfb79bb11dedd0ae748505863ab3ab731269cd71a2c2fbd159b3", + "000000000266dfb79bb11dedd0ae748505863ab3ab731269cd71a2c2fbd159b3", 0 - ], + ], [ - "00000000349ff0119d5c0dd8ffad8bf41cd6126a88416148b81fa4dcaebc42e1", + "00000000349ff0119d5c0dd8ffad8bf41cd6126a88416148b81fa4dcaebc42e1", 0 - ], + ], [ - "000000003c61939b4799eeea4335218d30de9b1071605126d719dce0f0d14810", + "000000003c61939b4799eeea4335218d30de9b1071605126d719dce0f0d14810", 0 - ], + ], [ - "000000003d9284570ed648d2b12ad24046ac8b9abcf05c4e9813ea110490cf73", + "000000003d9284570ed648d2b12ad24046ac8b9abcf05c4e9813ea110490cf73", 0 - ], + ], [ - "0000000001360b66e6dc0ccfbd75356034e721ae55c3d5c71a58be5d281c252b", + "0000000001360b66e6dc0ccfbd75356034e721ae55c3d5c71a58be5d281c252b", 0 - ], + ], [ - "000000000c114f42504916bfb2ee26ed8307b3f7f74226c1cfe1f5302ec23d26", + "000000000c114f42504916bfb2ee26ed8307b3f7f74226c1cfe1f5302ec23d26", 0 - ], + ], [ - "0000000007acac3fcf97b4ca81821263b704364adaa2736fce0a0722bfed4f8d", + "0000000007acac3fcf97b4ca81821263b704364adaa2736fce0a0722bfed4f8d", 0 - ], + ], [ - "00000000059768ef7731d27f9c2be48c6e16d7cb56680625f08ff25ead504280", + "00000000059768ef7731d27f9c2be48c6e16d7cb56680625f08ff25ead504280", 0 - ], + ], [ - "000000000351c8908f1f52518ce4bd251b896ca3fbccb69a2607db6624bafcfc", + "000000000351c8908f1f52518ce4bd251b896ca3fbccb69a2607db6624bafcfc", 0 - ], + ], [ - "0000000068d7ccae048e212e9e2ecb4d944f583b4490df4fbf654b4915597052", + "0000000068d7ccae048e212e9e2ecb4d944f583b4490df4fbf654b4915597052", 0 - ], + ], [ - "000000000e2aaa36417187233ff55325473bd5b7a164b358da60c96d1920fd77", + "000000000e2aaa36417187233ff55325473bd5b7a164b358da60c96d1920fd77", 0 - ], + ], [ - "000000001eb11ef6dbe0647bc87a8d218f6e59c2b9690f17edcf0dbd39cd0308", + "000000001eb11ef6dbe0647bc87a8d218f6e59c2b9690f17edcf0dbd39cd0308", 0 - ], + ], [ - "00000000022e7855e24cc3fff67ce093242434a8ffa45882333a0f08a40aad9c", + "00000000022e7855e24cc3fff67ce093242434a8ffa45882333a0f08a40aad9c", 0 - ], + ], [ - "000000000210130ff4e3186258c09a8463c1e196f5c5432b4c7b6954e907bf63", + "000000000210130ff4e3186258c09a8463c1e196f5c5432b4c7b6954e907bf63", 0 - ], + ], [ - "0000000000e01372ede322bf88ee5ed8a46dd4fd8df832eca16180263fc8b1ef", + "0000000000e01372ede322bf88ee5ed8a46dd4fd8df832eca16180263fc8b1ef", 0 - ], + ], [ - "00000000a0701896e26d5d884834b267512e0af52c92edc4bccf1c5c803d3c4f", + "00000000a0701896e26d5d884834b267512e0af52c92edc4bccf1c5c803d3c4f", 0 - ], + ], [ - "00000000869fc8d9ac1588f3e5bdfd60253e9824083800b7794010e0e9c6b6fe", + "00000000869fc8d9ac1588f3e5bdfd60253e9824083800b7794010e0e9c6b6fe", 0 - ], + ], [ - "000000001d43b3165ec30736f28f0761600b092686f861db23ec38f2d92b0ec6", + "000000001d43b3165ec30736f28f0761600b092686f861db23ec38f2d92b0ec6", 0 - ], + ], [ - "000000000ef4092da8c2056e5933de0e1530194c3ad941a9b393fbb26f98862e", + "000000000ef4092da8c2056e5933de0e1530194c3ad941a9b393fbb26f98862e", 0 - ], + ], [ - "0000000001e3fed39f70023909f962bea146b03bc8e94e5d19d7da93123f4f64", + "0000000001e3fed39f70023909f962bea146b03bc8e94e5d19d7da93123f4f64", 0 - ], + ], [ - "0000000000b4b8c877bbe3cde97649845290bb78999ecff4621b9bf2ab16aa2e", + "0000000000b4b8c877bbe3cde97649845290bb78999ecff4621b9bf2ab16aa2e", 0 - ], + ], [ - "00000000006095ba3b4742883a0ec427a3fd685ffb65b987ea77ebfedea7da82", + "00000000006095ba3b4742883a0ec427a3fd685ffb65b987ea77ebfedea7da82", 0 - ], + ], [ - "000000000168f0a76a6068a34fc042553aff4aa63b906028f28c2a4c327328e1", + "000000000168f0a76a6068a34fc042553aff4aa63b906028f28c2a4c327328e1", 0 - ], + ], [ - "0000000000af10f3079b4989ac4ff0baaecab38220510cdae9672d6922e93919", + "0000000000af10f3079b4989ac4ff0baaecab38220510cdae9672d6922e93919", 0 - ], + ], [ - "0000000000312791ada0f6a4c5eaf2a1cd57cd06f5970a8ab49923817b862c35", + "0000000000312791ada0f6a4c5eaf2a1cd57cd06f5970a8ab49923817b862c35", 0 - ], + ], [ - "000000000055f3d4f45c4d199d9c230cb2cfeb68c8e934cfd061bd616358655a", + "000000000055f3d4f45c4d199d9c230cb2cfeb68c8e934cfd061bd616358655a", 0 - ], + ], [ - "000000000036b6129bb5a786bfdd75cb4b932f7dcae9da469d3ba35096f1e821", + "000000000036b6129bb5a786bfdd75cb4b932f7dcae9da469d3ba35096f1e821", 0 - ], + ], [ - "00000000002fbccf271c13e486673251ecd7951ecc12ee73c4390e0ff09e9b59", + "00000000002fbccf271c13e486673251ecd7951ecc12ee73c4390e0ff09e9b59", 0 - ], + ], [ - "0000000000314e297a81bf002fc40eb391d8883ea45ee4e782385aa0fdba6452", + "0000000000314e297a81bf002fc40eb391d8883ea45ee4e782385aa0fdba6452", 0 - ], + ], [ - "00000000d3c473819ec3b3c268f7b555df22772e407bc8f246a47cfc579ec61f", + "00000000d3c473819ec3b3c268f7b555df22772e407bc8f246a47cfc579ec61f", 0 - ], + ], [ - "0000000075a438fda6bdb391263d0a2a6e8e68edd9dd8f70fe5734eab9351eb8", + "0000000075a438fda6bdb391263d0a2a6e8e68edd9dd8f70fe5734eab9351eb8", 0 - ], + ], [ - "0000000017ebae0a2bec50008b4a4ea8839798cbd9ff228e76aba087d0ff1736", + "0000000017ebae0a2bec50008b4a4ea8839798cbd9ff228e76aba087d0ff1736", 0 - ], + ], [ - "000000000800466ba31c0bbc12b125f16d05ed27788de045e25d6f093817d29c", + "000000000800466ba31c0bbc12b125f16d05ed27788de045e25d6f093817d29c", 0 - ], + ], [ - "00000000002163c41f2264f202e611aeb9ba6c0a3ee95cd8e5e7e571edc64edf", + "00000000002163c41f2264f202e611aeb9ba6c0a3ee95cd8e5e7e571edc64edf", 0 - ], + ], [ - "0000000000de9882d417786fce8c755cfaad17f40cda744d4badedfe5e414e31", + "0000000000de9882d417786fce8c755cfaad17f40cda744d4badedfe5e414e31", 0 - ], + ], [ - "00000000002af352cf41f60a5ebf033bf7e4967c0597cee706ba877b795aefb4", + "00000000002af352cf41f60a5ebf033bf7e4967c0597cee706ba877b795aefb4", 0 - ], + ], [ - "0000000000009ca0030f1dd0b09cc628f2d4d278c87b20781a1b136dc395debf", + "0000000000009ca0030f1dd0b09cc628f2d4d278c87b20781a1b136dc395debf", 0 - ], + ], [ - "00000000ffd27370a76d06a0da0e3805f47e35e2cf584d73d2c5ecaa2e525642", + "00000000ffd27370a76d06a0da0e3805f47e35e2cf584d73d2c5ecaa2e525642", 0 - ], + ], [ - "00000000720da6910aa75099baa020cb8db37e1dc19cdff66152225b7609c23a", + "00000000720da6910aa75099baa020cb8db37e1dc19cdff66152225b7609c23a", 0 - ], + ], [ - "000000000a5c2cc704bce5e8527ce91bac7430c659624ecd86e6a1bb9b697962", + "000000000a5c2cc704bce5e8527ce91bac7430c659624ecd86e6a1bb9b697962", 0 - ], + ], [ - "00000000084273545134e9a06483c8fab00c2b0628056bb1967f310c74a971bc", + "00000000084273545134e9a06483c8fab00c2b0628056bb1967f310c74a971bc", 0 - ], + ], [ - "0000000002f66f4da52804647b1c3e1f89d17bdb05e9cd4ebbd922007c773f21", + "0000000002f66f4da52804647b1c3e1f89d17bdb05e9cd4ebbd922007c773f21", 0 - ], + ], [ - "00000000c46146c9d0a67a354b3f82947e52670a3bded6d8513ab34a68ae18bd", + "00000000c46146c9d0a67a354b3f82947e52670a3bded6d8513ab34a68ae18bd", 0 - ], + ], [ - "000000002f61c429d7dbe7bde75796086efe574998766806138710a2d6001eba", + "000000002f61c429d7dbe7bde75796086efe574998766806138710a2d6001eba", 0 - ], + ], [ - "0000000001daf3e3e78a57df2c2d2ddd14093d10515925e75c818bec3bbd30c2", + "0000000001daf3e3e78a57df2c2d2ddd14093d10515925e75c818bec3bbd30c2", 0 - ], + ], [ - "0000000002e133a7427a9aac6ceca969b27507c14111a45512cdf8f52a436de0", + "0000000002e133a7427a9aac6ceca969b27507c14111a45512cdf8f52a436de0", 0 - ], + ], [ - "0000000000f7c4374d458666740de1d0e8c55229a209ced7c38e38708781487c", + "0000000000f7c4374d458666740de1d0e8c55229a209ced7c38e38708781487c", 0 - ], + ], [ - "000000000035bb9ea329ba30b83eeb4ea6f57c2fe703b97f9b879f21e22643e0", + "000000000035bb9ea329ba30b83eeb4ea6f57c2fe703b97f9b879f21e22643e0", 0 - ], + ], [ - "00000000001220503e0aaee266bca85de09ce97b0091f24972d1ad1c8afe8609", + "00000000001220503e0aaee266bca85de09ce97b0091f24972d1ad1c8afe8609", 0 - ], + ], [ - "000000000010a614c60457f8d2ae2bb826d037f52113252888fadda8ed773c9c", + "000000000010a614c60457f8d2ae2bb826d037f52113252888fadda8ed773c9c", 0 - ], + ], [ - "00000000585a8b882ecff8aa8434feeac4ef199ca669bd81ed473e37f0bb4528", + "00000000585a8b882ecff8aa8434feeac4ef199ca669bd81ed473e37f0bb4528", 0 - ], + ], [ - "000000009504ffdb5fe82ad88218fb5e75a8bc185247e30e22d23b9fd9b7f282", + "000000009504ffdb5fe82ad88218fb5e75a8bc185247e30e22d23b9fd9b7f282", 0 - ], + ], [ - "000000000ddec7d73bcd653168d82e34cf5746e006bccda8a9c031c3289b9568", + "000000000ddec7d73bcd653168d82e34cf5746e006bccda8a9c031c3289b9568", 0 - ], + ], [ - "000000000cb6620ee4e8cb8b6b4d51251e5961f7ae2e83538ab3a4fef3bcc773", + "000000000cb6620ee4e8cb8b6b4d51251e5961f7ae2e83538ab3a4fef3bcc773", 0 - ], + ], [ - "000000000239224a0841738513c1eda712b73266ea958aa75f44a3985ebfab82", + "000000000239224a0841738513c1eda712b73266ea958aa75f44a3985ebfab82", 0 - ], + ], [ - "00000000002630c7c3586fcc19079300403c54dc293bcfdf8a9981f85a5c31bc", + "00000000002630c7c3586fcc19079300403c54dc293bcfdf8a9981f85a5c31bc", 0 - ], + ], [ - "000000000028d8c34f44e51fd71f5401094a983f6566e6d08ce86ec5d1bd639c", + "000000000028d8c34f44e51fd71f5401094a983f6566e6d08ce86ec5d1bd639c", 0 - ], + ], [ - "00000000000dca95f1828adc3c37b4625f60aeb35a6614a4358322b7a6bc2f7d", + "00000000000dca95f1828adc3c37b4625f60aeb35a6614a4358322b7a6bc2f7d", 0 - ], + ], [ - "00000000d72ec84fda18959ddc474d1a31a3a13b1d94695136c4810af8c01a0b", + "00000000d72ec84fda18959ddc474d1a31a3a13b1d94695136c4810af8c01a0b", 0 - ], + ], [ - "00000000327c29604996eb7f0a208160969ee4408a1cad277a956334f94e0f35", + "00000000327c29604996eb7f0a208160969ee4408a1cad277a956334f94e0f35", 0 - ], + ], [ - "000000000e1bd41d009c1910fcfee7bf1cc1adb04b0b7a632ac36c1092f01bb7", + "000000000e1bd41d009c1910fcfee7bf1cc1adb04b0b7a632ac36c1092f01bb7", 0 - ], + ], [ - "000000000201a5afed48b9d095b949229e9882ef8bc96767be3097c87264dfb6", + "000000000201a5afed48b9d095b949229e9882ef8bc96767be3097c87264dfb6", 0 - ], + ], [ - "00000000003f28e8f3f9c80b1269bb0aa3b57501c12458550ef04fd43aca6a33", + "00000000003f28e8f3f9c80b1269bb0aa3b57501c12458550ef04fd43aca6a33", 0 - ], + ], [ - "000000000029e09fc14e38a6a0103c8c67383f41af7d76998055682525f4ca89", + "000000000029e09fc14e38a6a0103c8c67383f41af7d76998055682525f4ca89", 0 - ], + ], [ - "00000000285ce297602995582ba5d32d583d618a6a92643566e25dd36cf2b7ab", + "00000000285ce297602995582ba5d32d583d618a6a92643566e25dd36cf2b7ab", 0 - ], + ], [ - "00000000657045fa54fac52b8480dc84bd4c418940ba63679f4bd6add6a39962", + "00000000657045fa54fac52b8480dc84bd4c418940ba63679f4bd6add6a39962", 0 - ], + ], [ - "0000000017b7bb58be05a47ff7c4ead27db750813d6bcf3f99cbcc35324cf445", + "0000000017b7bb58be05a47ff7c4ead27db750813d6bcf3f99cbcc35324cf445", 0 - ], + ], [ - "00000000003a310e39b6df17f17450496b4f5c1593399bfa1ab8b4d39bac9b25", + "00000000003a310e39b6df17f17450496b4f5c1593399bfa1ab8b4d39bac9b25", 0 - ], + ], [ - "00000000000bfbc5294f003548a9636ebbcea3ba42577821266317676fbc363c", + "00000000000bfbc5294f003548a9636ebbcea3ba42577821266317676fbc363c", 0 - ], + ], [ - "000000002329351dd70c24da2eea5ac19f65b6053c4611aa4eb93bcc2783c57e", + "000000002329351dd70c24da2eea5ac19f65b6053c4611aa4eb93bcc2783c57e", 0 - ], + ], [ - "000000004ce02f1005aa6fa4d158c6e4fce95ab053d88ae74881dd080c24e057", + "000000004ce02f1005aa6fa4d158c6e4fce95ab053d88ae74881dd080c24e057", 0 - ], + ], [ - "0000000000fdaaa54cdaade8cfb75245de0747c60c0307ad11be9fe154535565", + "0000000000fdaaa54cdaade8cfb75245de0747c60c0307ad11be9fe154535565", 0 - ], + ], [ - "0000000003dc49f7472f960eedb4fb2d1ccc8b0530ca6c75ed2bba9718b6f297", + "0000000003dc49f7472f960eedb4fb2d1ccc8b0530ca6c75ed2bba9718b6f297", 0 - ], + ], [ - "00000000014ca604d769d4b99fff03ae3ac84d1e8eb991c5dac7c3cd4d9e68ee", + "00000000014ca604d769d4b99fff03ae3ac84d1e8eb991c5dac7c3cd4d9e68ee", 0 - ], + ], [ - "0000000000190ab8ecef3a3d5583563851672d81a4d4d952b8cf3bd503c655e5", + "0000000000190ab8ecef3a3d5583563851672d81a4d4d952b8cf3bd503c655e5", 0 - ], + ], [ - "00000000001204d263b607987fab11e1c19c94b7e3e674cc73cc2fb7b05fbf07", + "00000000001204d263b607987fab11e1c19c94b7e3e674cc73cc2fb7b05fbf07", 0 - ], + ], [ - "0000000000141e8d7f7ac359a8ae58e35ce6010c25ddd6f1881f41c0b939332e", + "0000000000141e8d7f7ac359a8ae58e35ce6010c25ddd6f1881f41c0b939332e", 0 - ], + ], [ - "00000000946344dd06ef5ddd13fb74f20c475daf911ff4e3f1dcdf64c330e274", + "00000000946344dd06ef5ddd13fb74f20c475daf911ff4e3f1dcdf64c330e274", 0 - ], + ], [ - "00000000ec77a7892e48b85bcbaf404d16d7fc93747d7e9e3ba6195a9b6f1525", + "00000000ec77a7892e48b85bcbaf404d16d7fc93747d7e9e3ba6195a9b6f1525", 0 - ], + ], [ - "0000000018a305c04dea8e93e423ce9569872e0ec5af49d23a0e3872b0ad6297", + "0000000018a305c04dea8e93e423ce9569872e0ec5af49d23a0e3872b0ad6297", 0 - ], + ], [ - "00000000055e32c5f8a86c9a712eeb6440bbf9810ae6da12d0cea2493138a885", + "00000000055e32c5f8a86c9a712eeb6440bbf9810ae6da12d0cea2493138a885", 0 - ], + ], [ - "0000000001913fcbe67badbce4234e86e35a1ea867ecd69814b5f5ab039b7d4b", + "0000000001913fcbe67badbce4234e86e35a1ea867ecd69814b5f5ab039b7d4b", 0 - ], + ], [ - "00000000002c71fe4403aee704720ceafd21f9f8c9c97a8bfbd25bb46223aa40", + "00000000002c71fe4403aee704720ceafd21f9f8c9c97a8bfbd25bb46223aa40", 0 - ], + ], [ - "0000000000343a42da0c811836d0785c272591facd816f0e7fdcfb1109d8f9a8", + "0000000000343a42da0c811836d0785c272591facd816f0e7fdcfb1109d8f9a8", 0 - ], + ], [ - "00000000000309b182608b3eea7fafd0d72e3c79a0a3a9cda03cde3947e332e1", + "00000000000309b182608b3eea7fafd0d72e3c79a0a3a9cda03cde3947e332e1", 0 - ], + ], [ - "00000000000204cc04e421c3958a64d7bc024a474ce792d42ab5b48a5a6f3927", + "00000000000204cc04e421c3958a64d7bc024a474ce792d42ab5b48a5a6f3927", 0 - ], + ], [ - "000000005eaa010e7255bd37e0b00780575074a74d889e17c4dbc578f917348d", + "000000005eaa010e7255bd37e0b00780575074a74d889e17c4dbc578f917348d", 0 - ], + ], [ - "00000000a0d425f62d9196c069286dc6635ded9d027de40070d397e45bd63e0e", + "00000000a0d425f62d9196c069286dc6635ded9d027de40070d397e45bd63e0e", 0 - ], + ], [ - "000000003355fd37068ce2d5d2a94ef964eeb9b687f21f4a00850a3e6cc4a71f", + "000000003355fd37068ce2d5d2a94ef964eeb9b687f21f4a00850a3e6cc4a71f", 0 - ], + ], [ - "000000000ca9148dabe9424cd8c96860c90d836ab25970a3e91856764e2e640c", + "000000000ca9148dabe9424cd8c96860c90d836ab25970a3e91856764e2e640c", 0 - ], + ], [ - "0000000000bde23f829dde8edef35436be4b8978da21fd2c3a8100ef5334e3cc", + "0000000000bde23f829dde8edef35436be4b8978da21fd2c3a8100ef5334e3cc", 0 - ], + ], [ - "000000000028bb26f1427fbfabeae65d55a9e59e18230713e40f0f7c9c2dee12", + "000000000028bb26f1427fbfabeae65d55a9e59e18230713e40f0f7c9c2dee12", 0 - ], + ], [ - "00000000002ac05422d254e597ee6b5e0f8be9b3e2f887486442d720c7766919", + "00000000002ac05422d254e597ee6b5e0f8be9b3e2f887486442d720c7766919", 0 - ], + ], [ - "00000000000e36d0b6f187dd9601b1d1dcd987c3e0f6a081ffd039c7c5e32462", + "00000000000e36d0b6f187dd9601b1d1dcd987c3e0f6a081ffd039c7c5e32462", 0 - ], + ], [ - "0000000000048d7b1f2a2a11fda34a5cfeea067ab03e482931e5a0f463f438ba", + "0000000000048d7b1f2a2a11fda34a5cfeea067ab03e482931e5a0f463f438ba", 0 - ], + ], [ - "00000000f780ab88c8a4f4247573a749fbb087a4e3fb6a7d29926de8a9ab3462", + "00000000f780ab88c8a4f4247573a749fbb087a4e3fb6a7d29926de8a9ab3462", 0 - ], + ], [ - "000000000313bbe6a940e6a8c40ba091aa1ebbaad135bbbff3ed8ae07cf574d2", + "000000000313bbe6a940e6a8c40ba091aa1ebbaad135bbbff3ed8ae07cf574d2", 0 - ], + ], [ - "000000001d4ab29721aa2722482562670a0d71dc1eb73231c5dafb64756b04e8", + "000000001d4ab29721aa2722482562670a0d71dc1eb73231c5dafb64756b04e8", 0 - ], + ], [ - "0000000006588bcbdec38d19962b96cf0352cbf1b90f3379cc6787d018cdb96d", + "0000000006588bcbdec38d19962b96cf0352cbf1b90f3379cc6787d018cdb96d", 0 - ], + ], [ - "000000000022e79539a21ac24f9daa2cbddf2bb4a3125f88a5efc20d13ea856b", + "000000000022e79539a21ac24f9daa2cbddf2bb4a3125f88a5efc20d13ea856b", 0 - ], + ], [ - "0000000000dd284b7fee584cc578a10fbe57e8efe6bf6ebacb23c0ac5d46cdf7", + "0000000000dd284b7fee584cc578a10fbe57e8efe6bf6ebacb23c0ac5d46cdf7", 0 - ], + ], [ - "00000000001451143787f411c93d5506065c3fb597966f2fd7a4a5c078ee6aa2", + "00000000001451143787f411c93d5506065c3fb597966f2fd7a4a5c078ee6aa2", 0 - ], + ], [ - "00000000000ca977394af1e414dc1f9d83efa007f7226e11d3a00f59a1fdfad1", + "00000000000ca977394af1e414dc1f9d83efa007f7226e11d3a00f59a1fdfad1", 0 - ], + ], [ - "0000000000011f8caa80580e7a796bbce5b84e60731bf48e03c6ff5c6bba868e", + "0000000000011f8caa80580e7a796bbce5b84e60731bf48e03c6ff5c6bba868e", 0 - ], + ], [ - "000000000001705beb1376af1af08b437acef6befbe7d3b60c5fbaf6bb7f38c9", + "000000000001705beb1376af1af08b437acef6befbe7d3b60c5fbaf6bb7f38c9", 0 - ], + ], [ - "000000000000c838f1f45422d93ca9b5838368a37423efa8439ee24b2bf247a2", + "000000000000c838f1f45422d93ca9b5838368a37423efa8439ee24b2bf247a2", 0 - ], + ], [ - "00000000000111ad857d31d07fdc8b32d17af2522c18bdaccfef449b29d17362", + "00000000000111ad857d31d07fdc8b32d17af2522c18bdaccfef449b29d17362", 0 - ], + ], [ - "000000000000312a7718fc616b0ecfdbf6066f71ec1a4a8c43f50f02f61cc398", + "000000000000312a7718fc616b0ecfdbf6066f71ec1a4a8c43f50f02f61cc398", 0 - ], + ], [ - "0000000000007d232b217a59b804ef67091c5720a5460c2c16bf97b97a24801e", + "0000000000007d232b217a59b804ef67091c5720a5460c2c16bf97b97a24801e", 0 - ], + ], [ - "000000000000177235c33695aced585685b4c500eb76e72caad02e17503900eb", + "000000000000177235c33695aced585685b4c500eb76e72caad02e17503900eb", 0 - ], + ], [ - "00000000000037f5c5890da7a8e2acd2b0669ad7db648ac43140c637a1c81637", + "00000000000037f5c5890da7a8e2acd2b0669ad7db648ac43140c637a1c81637", 0 - ], + ], [ - "0000000000002123904063f223bc35135c426a4f9a0b74c1907e837b810f0321", + "0000000000002123904063f223bc35135c426a4f9a0b74c1907e837b810f0321", 0 - ], + ], [ - "0000000000000961db809da357d91a9341170fafef9f24896d8730bd05cf3f96", + "0000000000000961db809da357d91a9341170fafef9f24896d8730bd05cf3f96", 0 - ], + ], [ - "000000000d2e8fcd05eb874e98cfc3a6e239f6974950e6f50b0487513ecab760", + "000000000d2e8fcd05eb874e98cfc3a6e239f6974950e6f50b0487513ecab760", 0 - ], + ], [ - "00000000017e362508c8db23fae0431eaed708d9db13e48fd5d318066bf6733f", + "00000000017e362508c8db23fae0431eaed708d9db13e48fd5d318066bf6733f", 0 - ], + ], [ - "000000000011b2bc4fe36f90b7ba5a62f974db250bfdc285b70c71148023c7e3", + "000000000011b2bc4fe36f90b7ba5a62f974db250bfdc285b70c71148023c7e3", 0 - ], + ], [ - "000000000001be28570b378dd5dd2eb3aa495c229913b6757fe8900dfa3cce99", + "000000000001be28570b378dd5dd2eb3aa495c229913b6757fe8900dfa3cce99", 0 - ], + ], [ - "0000000000242bd0bb16d0a5324e0b4b5a83697dabb3b4a059084557478e50b9", + "0000000000242bd0bb16d0a5324e0b4b5a83697dabb3b4a059084557478e50b9", 0 - ], + ], [ - "0000000000d8ce69d18da32ed52e503d6b5ad48d970b90545f956b2d2af2edf6", + "0000000000d8ce69d18da32ed52e503d6b5ad48d970b90545f956b2d2af2edf6", 0 - ], + ], [ - "0000000000366655bf0cb3dd0cd7801e0adbd26b5b441b77a9e3642597effb00", + "0000000000366655bf0cb3dd0cd7801e0adbd26b5b441b77a9e3642597effb00", 0 - ], + ], [ - "00000000000dc7aa00d4607ca8374d40d1187f1c084b620edb45fc39bc8d2db8", + "00000000000dc7aa00d4607ca8374d40d1187f1c084b620edb45fc39bc8d2db8", 0 - ], + ], [ - "000000000003baf60d9c6e70a765cf517f66a124509191188e9547ad09edf68b", + "000000000003baf60d9c6e70a765cf517f66a124509191188e9547ad09edf68b", 0 - ], + ], [ - "000000000000e0f476893b8fb4d37e855353075fde73dbc1fe181cc956349f19", + "000000000000e0f476893b8fb4d37e855353075fde73dbc1fe181cc956349f19", 0 - ], + ], [ - "00000000000032ed16b7de758abadf4a4fb2df7a101ff275c51f29e1555a89a5", + "00000000000032ed16b7de758abadf4a4fb2df7a101ff275c51f29e1555a89a5", 0 - ], + ], [ - "0000000000000a564d03f0f2fe20f6fb5f038d931f732d817641cd7fff3b0acd", + "0000000000000a564d03f0f2fe20f6fb5f038d931f732d817641cd7fff3b0acd", 0 - ], + ], [ - "000000000000011aa4d0fdcea8d4ca85cd5d548e322e2b6abd17f8444be855c5", + "000000000000011aa4d0fdcea8d4ca85cd5d548e322e2b6abd17f8444be855c5", 0 - ], + ], [ - "0000000000000610588540267a0eb544531047d4c8af0f21fca7cd3d96205cfc", + "0000000000000610588540267a0eb544531047d4c8af0f21fca7cd3d96205cfc", 0 - ], + ], [ - "00000000000002770dab5e14843149df8f76b8dc8458ed3ed2ed8a14a6e2e564", + "00000000000002770dab5e14843149df8f76b8dc8458ed3ed2ed8a14a6e2e564", 0 - ], + ], [ - "00000000000006b70ebc9f75bd32f466602cbd4b86c3c2d2379059542bb8bec6", + "00000000000006b70ebc9f75bd32f466602cbd4b86c3c2d2379059542bb8bec6", 0 - ], + ], [ - "00000000000000ef579af389fa7674f98a2371063fa8b218c5ca0ad94e21b896", + "00000000000000ef579af389fa7674f98a2371063fa8b218c5ca0ad94e21b896", 0 - ], + ], [ - "000000000000021b6108dc988f9153383f9501ab9001109aa87902ddd4c8a4d1", + "000000000000021b6108dc988f9153383f9501ab9001109aa87902ddd4c8a4d1", 0 - ], + ], [ - "000000000000022c02ff22bc0af5201f0e1a14a75879c494731e4fbf999218c8", + "000000000000022c02ff22bc0af5201f0e1a14a75879c494731e4fbf999218c8", 0 - ], + ], [ - "000000000000032651c988edc1ccd08e82b888cbb8135e24a958ac0c0b640d5d", + "000000000000032651c988edc1ccd08e82b888cbb8135e24a958ac0c0b640d5d", 0 - ], + ], [ - "000000000000015aefdfa0790bed326c38c358c07aac0674f5b2e771258b8df3", + "000000000000015aefdfa0790bed326c38c358c07aac0674f5b2e771258b8df3", 0 - ], + ], [ - "00000000000000822e1534c86afef911b67d3fa20cf2b12d93d20d64005f54d7", + "00000000000000822e1534c86afef911b67d3fa20cf2b12d93d20d64005f54d7", 0 - ], + ], [ - "00000000000000338b871276768c923b1c603fd6150bd054c2287e532e61de7f", + "00000000000000338b871276768c923b1c603fd6150bd054c2287e532e61de7f", 0 - ], + ], [ - "00000000000002d0af52c0cae894bf836b61137ace2bd7500abd13a584c02741", + "00000000000002d0af52c0cae894bf836b61137ace2bd7500abd13a584c02741", 0 - ], + ], [ - "000000006f8443a458f38d8731821c07a2fda0ecdbb1cf797f541844d468ce0c", + "000000006f8443a458f38d8731821c07a2fda0ecdbb1cf797f541844d468ce0c", 0 - ], + ], [ - "0000000000b6fbd8b4e227f5514979a61d8b0b918d2adc154e585ca926386704", + "0000000000b6fbd8b4e227f5514979a61d8b0b918d2adc154e585ca926386704", 0 - ], + ], [ - "000000000f4f5e49b10278e27d9dee15b92f9d4a257138a206831e0c00188767", + "000000000f4f5e49b10278e27d9dee15b92f9d4a257138a206831e0c00188767", 0 - ], + ], [ - "0000000002c7e9769bd8ae9906fc5682e937b5c31ab5b5b86e4d70af2c15a95c", + "0000000002c7e9769bd8ae9906fc5682e937b5c31ab5b5b86e4d70af2c15a95c", 0 - ], + ], [ - "0000000000f68a1db8cd387e0a2f93f45149fe1ee4a230bb386313bdd42058e8", + "0000000000f68a1db8cd387e0a2f93f45149fe1ee4a230bb386313bdd42058e8", 0 - ], + ], [ - "0000000000f0f65c360c8f0f9853ad1142f16675dc1175d61afdbef977776b25", + "0000000000f0f65c360c8f0f9853ad1142f16675dc1175d61afdbef977776b25", 0 - ], + ], [ - "000000000004f734e634156511cbef7dfefebdf317e7488aa6c2562572d7ecb7", + "000000000004f734e634156511cbef7dfefebdf317e7488aa6c2562572d7ecb7", 0 - ], + ], [ - "0000000000002a46a7a16787e8317dc567ae26816324c2035be0186ba54d5cb8", + "0000000000002a46a7a16787e8317dc567ae26816324c2035be0186ba54d5cb8", 0 - ], + ], [ - "000000000001a593e6f01875b77e270163538d88452779bb557df7c2607c28e0", + "000000000001a593e6f01875b77e270163538d88452779bb557df7c2607c28e0", 0 - ], + ], [ - "0000000000004f24cfafa10bd50a452535f64be577a6161e51c7c71542f654c4", + "0000000000004f24cfafa10bd50a452535f64be577a6161e51c7c71542f654c4", 0 - ], + ], [ - "00000000597cce73e84b63f08cfcb9b01f5e7621752d8c8e08fabbd6ab5c0dd5", + "00000000597cce73e84b63f08cfcb9b01f5e7621752d8c8e08fabbd6ab5c0dd5", 0 - ], + ], [ - "000000007cad379df01247771fff471bc99faea1b86218602f45ab13efc5e9f6", + "000000007cad379df01247771fff471bc99faea1b86218602f45ab13efc5e9f6", 0 - ], + ], [ - "000000000d6085aab25892be49c49d6c0a3949befdc3ddce2faa46b104e1e804", + "000000000d6085aab25892be49c49d6c0a3949befdc3ddce2faa46b104e1e804", 0 - ], + ], [ - "0000000002be5996786b42d6a229093896aea9966b1854ea261e01e84da1f420", + "0000000002be5996786b42d6a229093896aea9966b1854ea261e01e84da1f420", 0 - ], + ], [ - "00000000002684b72056e270b115d80b12b2f68eac7412355287226aecd9b5e0", + "00000000002684b72056e270b115d80b12b2f68eac7412355287226aecd9b5e0", 0 - ], + ], [ - "0000000079ea27efb24366c87856a9e371c56fcbd59d09d3164a5c2fc15fcbca", + "0000000079ea27efb24366c87856a9e371c56fcbd59d09d3164a5c2fc15fcbca", 0 - ], + ], [ - "000000001694120525dba4548ca54087544da1fbefa51c38f0208d683418825d", + "000000001694120525dba4548ca54087544da1fbefa51c38f0208d683418825d", 0 - ], + ], [ - "000000000693e80d372938f3553151ab9d0a9a6922182591c701df739dc9a502", + "000000000693e80d372938f3553151ab9d0a9a6922182591c701df739dc9a502", 0 - ], + ], [ - "0000000002950d9cb23c8511937811910b712f73d448e6fdc2e39e029b86848b", + "0000000002950d9cb23c8511937811910b712f73d448e6fdc2e39e029b86848b", 0 - ], + ], [ - "000000000091c40056c6a48f33db17764af89c01f62ae653aa5e494146164cee", + "000000000091c40056c6a48f33db17764af89c01f62ae653aa5e494146164cee", 0 - ], + ], [ - "00000000001f373c47e1a39af4e1ebcd8c88411ec49d6bd520c2781564070971", + "00000000001f373c47e1a39af4e1ebcd8c88411ec49d6bd520c2781564070971", 0 - ], + ], [ - "00000000000809ca4b2170c57958709b867095b1972d80a2ee55359fbd0940fe", + "00000000000809ca4b2170c57958709b867095b1972d80a2ee55359fbd0940fe", 0 - ], + ], [ - "0000000000038e7bd66fc3308447b1370dbdd0661c427c512bdbc641ff360fb2", + "0000000000038e7bd66fc3308447b1370dbdd0661c427c512bdbc641ff360fb2", 0 - ], + ], [ - "000000009a3325df76e2de1fc1970cc2f241fa8a41da9ad745a0d9666d9ff51d", + "000000009a3325df76e2de1fc1970cc2f241fa8a41da9ad745a0d9666d9ff51d", 0 - ], + ], [ - "000000003176e92ff837bf43a48a995c1a321b166475f586ffb4b962e0254a4a", + "000000003176e92ff837bf43a48a995c1a321b166475f586ffb4b962e0254a4a", 0 - ], + ], [ - "0000000001ae3292e81ca3859b75bccd5bff825cd9f496efd085160c716ed05e", + "0000000001ae3292e81ca3859b75bccd5bff825cd9f496efd085160c716ed05e", 0 - ], + ], [ - "00000000033bdac4f0d36bb912fba28bb5caa54d1b611759a10f79ff3c969cf2", + "00000000033bdac4f0d36bb912fba28bb5caa54d1b611759a10f79ff3c969cf2", 0 - ], + ], [ - "00000000004c6db7fa0e2c9f08693abfeb128c5827b511a5c46c623a103b416b", + "00000000004c6db7fa0e2c9f08693abfeb128c5827b511a5c46c623a103b416b", 0 - ], + ], [ - "00000000003d87f48bb95e9431760d0c5f4f93c77d02fce9dd1673e9f5b01029", + "00000000003d87f48bb95e9431760d0c5f4f93c77d02fce9dd1673e9f5b01029", 0 - ], + ], [ - "00000000000e214fc3d8b97571eb75d248ca29f8e25a584c33de8488ceee72b0", + "00000000000e214fc3d8b97571eb75d248ca29f8e25a584c33de8488ceee72b0", 0 - ], + ], [ - "00000000000133269b7159b828700d02de770a8cbd91f3d166e6bbc95d8e0dfc", + "00000000000133269b7159b828700d02de770a8cbd91f3d166e6bbc95d8e0dfc", 0 - ], + ], [ - "000000000000cc92e2dd933a08f7fd87f84451627982fb66583587858217c059", + "000000000000cc92e2dd933a08f7fd87f84451627982fb66583587858217c059", 0 - ], + ], [ - "00000000000030708136c20c4c8216314005b3cb5c551ded33b26cf64d2ff47d", + "00000000000030708136c20c4c8216314005b3cb5c551ded33b26cf64d2ff47d", 0 - ], + ], [ - "00000000c472a1341d479ed02f31b699e448c035049a7092670b38f4ec6121f0", + "00000000c472a1341d479ed02f31b699e448c035049a7092670b38f4ec6121f0", 0 - ], + ], [ - "000000000a358834d6eed41b9b7161a338aba53828111414cdea7552ed15548a", + "000000000a358834d6eed41b9b7161a338aba53828111414cdea7552ed15548a", 0 - ], + ], [ - "000000000e13e77372daea775c8358916e57ed11835899c14e5140ed9be11089", + "000000000e13e77372daea775c8358916e57ed11835899c14e5140ed9be11089", 0 - ], + ], [ - "00000000008252cd0931f94b2465bd4f93e4bfeec6697962c5b034cf3d12cf7c", + "00000000008252cd0931f94b2465bd4f93e4bfeec6697962c5b034cf3d12cf7c", 0 - ], + ], [ - "00000000019812cd6cde3a43831234be71e68118be24a80161349b8b327acb5b", + "00000000019812cd6cde3a43831234be71e68118be24a80161349b8b327acb5b", 0 - ], + ], [ - "00000000005865499f301adfb59f8380743e4c3b3ab220ca4eb97dc6628df626", + "00000000005865499f301adfb59f8380743e4c3b3ab220ca4eb97dc6628df626", 0 - ], + ], [ - "000000000015f77e1e61329560a4378eb401fa5bf0ef90b0a014a4d7857ca7a8", + "000000000015f77e1e61329560a4378eb401fa5bf0ef90b0a014a4d7857ca7a8", 0 - ], + ], [ - "00000000e9cbcbb625e8a463ba8e7f14be46ba9538ffe93338784ccad3d992e8", + "00000000e9cbcbb625e8a463ba8e7f14be46ba9538ffe93338784ccad3d992e8", 0 - ], + ], [ - "000000000fb27169efcc2873cfaac223ebb91cc5e1e5ad7e9a312d42bedf7c42", + "000000000fb27169efcc2873cfaac223ebb91cc5e1e5ad7e9a312d42bedf7c42", 0 - ], + ], [ - "000000000c9c96d62ebfbf3fa4003f1d46d175140ab084dee17e8125fa40f24a", + "000000000c9c96d62ebfbf3fa4003f1d46d175140ab084dee17e8125fa40f24a", 0 - ], + ], [ - "000000000311e3a766b1ab2064b68a344a561eb496d595126808ffb166c71cc1", + "000000000311e3a766b1ab2064b68a344a561eb496d595126808ffb166c71cc1", 0 - ], + ], [ - "00000000677568c82262ac3a4ca3f909bdfb0b35145ad490fa3fbdc719d06b91", + "00000000677568c82262ac3a4ca3f909bdfb0b35145ad490fa3fbdc719d06b91", 0 - ], + ], [ - "000000000ee77ba9ab657e51fd9140f5c9b46731d9341e98188f929c97d04746", + "000000000ee77ba9ab657e51fd9140f5c9b46731d9341e98188f929c97d04746", 0 - ], + ], [ - "0000000008a67eb9c91a6d74168f3f385270fa942ea00bdd31924d1b6ea11148", + "0000000008a67eb9c91a6d74168f3f385270fa942ea00bdd31924d1b6ea11148", 0 - ], + ], [ - "00000000017f93c9e0026e90d579e18c83b4a8557f0c00e9b85ab164cf4466c5", + "00000000017f93c9e0026e90d579e18c83b4a8557f0c00e9b85ab164cf4466c5", 0 - ], + ], [ - "0000000000994efa379235c03711a8e6b29895d928b5fde96cb01c02374c0602", + "0000000000994efa379235c03711a8e6b29895d928b5fde96cb01c02374c0602", 0 - ], + ], [ - "00000000b3be9f23c943d71d7c7dbdf6dd672d77a712f6c83e9796a85e4379f2", + "00000000b3be9f23c943d71d7c7dbdf6dd672d77a712f6c83e9796a85e4379f2", 0 - ], + ], [ - "000000000713e1089b0b2bdcba462b740c9396f822f1c73e090713978a7f1314", + "000000000713e1089b0b2bdcba462b740c9396f822f1c73e090713978a7f1314", 0 - ], + ], [ - "0000000002fc44d358401a7ac9ce4ddcb17f3cbac08e40242e755e60ab2292ed", + "0000000002fc44d358401a7ac9ce4ddcb17f3cbac08e40242e755e60ab2292ed", 0 - ], + ], [ - "00000000021ef2c04fd30be7049f73b9a8353ac96a467dd5f0b9c1457be1bc5e", + "00000000021ef2c04fd30be7049f73b9a8353ac96a467dd5f0b9c1457be1bc5e", 0 - ], + ], [ - "000000000023b95b440ccbbdcb914172cf675cd15d6111bd7f5a436a4925d36e", + "000000000023b95b440ccbbdcb914172cf675cd15d6111bd7f5a436a4925d36e", 0 - ], + ], [ - "00000000001983521dbffd1b742a6d4b5dfda3f46579fbbdd83a2ebf9a039bec", + "00000000001983521dbffd1b742a6d4b5dfda3f46579fbbdd83a2ebf9a039bec", 0 - ], + ], [ - "0000000000044d53dbea312432e68fa90dc2148946f613216dbdeec86f6a67c1", + "0000000000044d53dbea312432e68fa90dc2148946f613216dbdeec86f6a67c1", 0 - ], + ], [ - "00000000000107667692f12d21a55a72ff1dce828f96872e36c35bfbae475a8d", + "00000000000107667692f12d21a55a72ff1dce828f96872e36c35bfbae475a8d", 0 - ], + ], [ - "000000000000252d1d0c01744ec25af801ef7c57e2581c95295070b6a8a85bd5", + "000000000000252d1d0c01744ec25af801ef7c57e2581c95295070b6a8a85bd5", 0 - ], + ], [ - "000000001c1da54e16dc06158677024d9e74bff39bfaec83434ac33673fcc251", + "000000001c1da54e16dc06158677024d9e74bff39bfaec83434ac33673fcc251", 0 - ], + ], [ - "00000000b4d0c6ae86bfdf7ba4c205fc3e6b3b6d63836b85e30e9d8bac922301", + "00000000b4d0c6ae86bfdf7ba4c205fc3e6b3b6d63836b85e30e9d8bac922301", 0 - ], + ], [ - "000000002b16179cb022bf678bd847dd6fc1908d0df04abf0c7874981eb33ee7", + "000000002b16179cb022bf678bd847dd6fc1908d0df04abf0c7874981eb33ee7", 0 - ], + ], [ - "000000000e6783554aae41856424d184dc4fa061f40676efd107e6f933a25641", + "000000000e6783554aae41856424d184dc4fa061f40676efd107e6f933a25641", 0 - ], + ], [ - "00000000005ae4acbab519895b4b523d97a09e381c9e4b044e642f73b8c0f1b0", + "00000000005ae4acbab519895b4b523d97a09e381c9e4b044e642f73b8c0f1b0", 0 - ], + ], [ - "000000000010372b59c9595d947064804b75ab21868dd075a3842ab7d2df6181", + "000000000010372b59c9595d947064804b75ab21868dd075a3842ab7d2df6181", 0 - ], + ], [ - "00000000002f9f587ea304093be049d3142ac0c92f9c68928a4f82d12b929b69", + "00000000002f9f587ea304093be049d3142ac0c92f9c68928a4f82d12b929b69", 0 - ], + ], [ - "000000000005d4cae51b3c76dc3c61bed0c265c4f228c0c4d1d3d147146c34eb", + "000000000005d4cae51b3c76dc3c61bed0c265c4f228c0c4d1d3d147146c34eb", 0 - ], + ], [ - "000000000001a5b6c0e0a0b485a490cb52ccdf9b22596656039b51545bb07be5", + "000000000001a5b6c0e0a0b485a490cb52ccdf9b22596656039b51545bb07be5", 0 - ], + ], [ - "000000000000d723d0976338edf55d08edab995dd6283cbb688855f0dca6e8f5", + "000000000000d723d0976338edf55d08edab995dd6283cbb688855f0dca6e8f5", 0 - ], + ], [ - "00000000bfebfae90208a82c7fa06c0f61674dbf1e4f9162e370656c38d611bb", + "00000000bfebfae90208a82c7fa06c0f61674dbf1e4f9162e370656c38d611bb", 0 - ], + ], [ - "000000000c91cd144b2a92ab5024c87f70cc1d76a4a7f26a82a98c5aaad62850", + "000000000c91cd144b2a92ab5024c87f70cc1d76a4a7f26a82a98c5aaad62850", 0 - ], + ], [ - "00000000077c8114eb5cfb69c3924c699d0c70334360dd1daa95db0db4816953", + "00000000077c8114eb5cfb69c3924c699d0c70334360dd1daa95db0db4816953", 0 - ], + ], [ - "000000000348a6443e091db8f68e88a10afad7c6e3e5392247902c4b4feade43", + "000000000348a6443e091db8f68e88a10afad7c6e3e5392247902c4b4feade43", 0 - ], + ], [ - "0000000000d63b70351e05829ad8a56336521b361b0d50eb7ea1f5b46c25b00a", + "0000000000d63b70351e05829ad8a56336521b361b0d50eb7ea1f5b46c25b00a", 0 - ], + ], [ - "00000000004658603163f0ede572120a1bbfce8d313aa282ae54d2ffd9fe9079", + "00000000004658603163f0ede572120a1bbfce8d313aa282ae54d2ffd9fe9079", 0 - ], + ], [ - "0000000000048063b410c793db34856f23acfb19a0ce72f5997fa572773378c8", + "0000000000048063b410c793db34856f23acfb19a0ce72f5997fa572773378c8", 0 - ], + ], [ - "00000000000228fb6e587fa593ff8b4764064bba8bfc2f43ba5b1f12af33d04a", + "00000000000228fb6e587fa593ff8b4764064bba8bfc2f43ba5b1f12af33d04a", 0 - ], + ], [ - "00000000000082e3ddb75c0ea2a98922b1556ce10346f9bb0cedd97ccb3fdf62", + "00000000000082e3ddb75c0ea2a98922b1556ce10346f9bb0cedd97ccb3fdf62", 0 - ], + ], [ - "00000000000005571b54d4886b44b81c21dfbefa554cd7c23430e5aeff6b5ae2", + "00000000000005571b54d4886b44b81c21dfbefa554cd7c23430e5aeff6b5ae2", 0 - ], + ], [ - "00000000306a603ca1a0d961e08e103a9f13f3615163c3373d1bd2a67cadc2a7", + "00000000306a603ca1a0d961e08e103a9f13f3615163c3373d1bd2a67cadc2a7", 0 - ], + ], [ - "00000000195d93ba7ae19832b622de86ebdadf3c78f1751ef2b2e9b0e3a530d8", + "00000000195d93ba7ae19832b622de86ebdadf3c78f1751ef2b2e9b0e3a530d8", 0 - ], + ], [ - "0000000000476d0d00cbc68bb20b4893f0e608b02a1e029b8c6c73e169c49e69", + "0000000000476d0d00cbc68bb20b4893f0e608b02a1e029b8c6c73e169c49e69", 0 - ], + ], [ - "000000000051348044bc10fc05960c244c3ccd3b3b6c145ffd9958a1c8bc0215", + "000000000051348044bc10fc05960c244c3ccd3b3b6c145ffd9958a1c8bc0215", 0 - ], + ], [ - "0000000001e4df369203badca9aedc28c240d592b12d284ce0b0463fc7537c09", + "0000000001e4df369203badca9aedc28c240d592b12d284ce0b0463fc7537c09", 0 - ], + ], [ - "000000000091cc1ccd448b0ec9185618a84dea96f52477cfb9b9ca2b60cebe83", + "000000000091cc1ccd448b0ec9185618a84dea96f52477cfb9b9ca2b60cebe83", 0 - ], + ], [ - "000000000024a50299c0ef0c6dec9c64336b6cf5c1a1b0013e22fd4fcee1d7d1", + "000000000024a50299c0ef0c6dec9c64336b6cf5c1a1b0013e22fd4fcee1d7d1", 0 - ], + ], [ - "00000000000349248c1df06c3783d1270cd97ce7f605b9036fca0fdc2f0fbb96", + "00000000000349248c1df06c3783d1270cd97ce7f605b9036fca0fdc2f0fbb96", 0 - ], + ], [ - "000000000001afe6793e7427a3d780876d26eb7f2ded92563f991bf7302aea69", + "000000000001afe6793e7427a3d780876d26eb7f2ded92563f991bf7302aea69", 0 - ], + ], [ - "0000000000007148006e139e24d9fccc307661c9a0cbcd1af983487c2f0780c9", + "0000000000007148006e139e24d9fccc307661c9a0cbcd1af983487c2f0780c9", 0 - ], + ], [ - "0000000000002734722a341984738177a3f6f264291424e4984f2128d921bf29", + "0000000000002734722a341984738177a3f6f264291424e4984f2128d921bf29", 0 - ], + ], [ - "000000000109b02caaa95e49a477757a41a42daed40e92f54fa09e63f5538cd2", + "000000000109b02caaa95e49a477757a41a42daed40e92f54fa09e63f5538cd2", 0 - ], + ], [ - "000000009a11c7ff8b8fa7fbff5a04c25906f701ab5bd67195736f9ccc839ab9", + "000000009a11c7ff8b8fa7fbff5a04c25906f701ab5bd67195736f9ccc839ab9", 0 - ], + ], [ - "000000002b1d77f8e0cd60af1c62ef6d381e8905665b15a7fbc546d0c1a45e18", + "000000002b1d77f8e0cd60af1c62ef6d381e8905665b15a7fbc546d0c1a45e18", 0 - ], + ], [ - "0000000002588cb017de9e2f23cea7edc5082f1b3faec890f9252d556efeac40", + "0000000002588cb017de9e2f23cea7edc5082f1b3faec890f9252d556efeac40", 0 - ], + ], [ - "00000000008b07f177adc24a4b1a64d2dbcfbcc903ba861d493e11d6b33af7dc", + "00000000008b07f177adc24a4b1a64d2dbcfbcc903ba861d493e11d6b33af7dc", 0 - ], + ], [ - "0000000000bab8db5020aa8e052165275e8eb3e7c843533246bf6e4c8374757e", + "0000000000bab8db5020aa8e052165275e8eb3e7c843533246bf6e4c8374757e", 0 - ], + ], [ - "0000000000138488fdca8bfc327e6dbd6c72c5f1dc5868d9c0ea886665b9b56b", + "0000000000138488fdca8bfc327e6dbd6c72c5f1dc5868d9c0ea886665b9b56b", 0 - ], + ], [ - "0000000000094021fc954efbf08be667fef1b817e8715d4093a561fc30264aa7", + "0000000000094021fc954efbf08be667fef1b817e8715d4093a561fc30264aa7", 0 - ], + ], [ - "000000000000e8183e64072db79adfc6c09b650c4178001be3fade4050b06005", + "000000000000e8183e64072db79adfc6c09b650c4178001be3fade4050b06005", 0 - ], + ], [ - "0000000000004c93e8661c75974cd191c68dd66999da4f70d039c0ba4a12b970", + "0000000000004c93e8661c75974cd191c68dd66999da4f70d039c0ba4a12b970", 0 - ], + ], [ - "00000000000021c675b3ec404bb996f5e68f9eeceeac6946e5a6822987824d33", + "00000000000021c675b3ec404bb996f5e68f9eeceeac6946e5a6822987824d33", 0 - ], + ], [ - "0000000000000ad85684d30f25d1ec34638f099df2f33b418a07307c68fe3c2d", + "0000000000000ad85684d30f25d1ec34638f099df2f33b418a07307c68fe3c2d", 0 - ], + ], [ - "000000000009c6add76ac42a1942c4ce74d25d1b8975d4e3ac8932185e785a44", + "000000000009c6add76ac42a1942c4ce74d25d1b8975d4e3ac8932185e785a44", 0 - ], + ], [ - "000000001e7d828d354716881683eb6fb5caec5d91afce298e4e3bcee9574924", + "000000001e7d828d354716881683eb6fb5caec5d91afce298e4e3bcee9574924", 0 - ], + ], [ - "000000000a0e438ab203d8fd3e56100f2f14759f704bff6c699df0bb4e9aad64", + "000000000a0e438ab203d8fd3e56100f2f14759f704bff6c699df0bb4e9aad64", 0 - ], + ], [ - "000000000b7d5c2895df8bc1fdf5d31e0f663564cb5cff3b18642c44a71b6248", + "000000000b7d5c2895df8bc1fdf5d31e0f663564cb5cff3b18642c44a71b6248", 0 - ], + ], [ - "000000000193209ecd92fce00a75975446423d94a325ed525c15d5ab921da273", + "000000000193209ecd92fce00a75975446423d94a325ed525c15d5ab921da273", 0 - ], + ], [ - "000000000020835bdc30ac67efdbc785d15186914bc14e86387f97450df46418", + "000000000020835bdc30ac67efdbc785d15186914bc14e86387f97450df46418", 0 - ], + ], [ - "00000000000c9078321f0030214c75e170b01ec664d39bab1b1e48460a54eb63", + "00000000000c9078321f0030214c75e170b01ec664d39bab1b1e48460a54eb63", 0 - ], + ], [ - "00000000000ac68b63d486ade190dc9108eb3730d25e7537649fe21c30e0121f", + "00000000000ac68b63d486ade190dc9108eb3730d25e7537649fe21c30e0121f", 0 - ], + ], [ - "000000000002a94dfc5f4b677b251a7a7647dbb99c0803df8658222227fe3e3f", + "000000000002a94dfc5f4b677b251a7a7647dbb99c0803df8658222227fe3e3f", 0 - ], + ], [ - "000000000000b076bbef0e50593b1595ffb3d571e7ad95dbdf06dca8824ef7f3", + "000000000000b076bbef0e50593b1595ffb3d571e7ad95dbdf06dca8824ef7f3", 0 - ], + ], [ - "000000000000167075c8bcd24233d25cd268271c0e8fcb6f301ee1b6f6ff0341", + "000000000000167075c8bcd24233d25cd268271c0e8fcb6f301ee1b6f6ff0341", 0 - ], + ], [ - "00000000013107aa587bcf12ac445330ff0325d73c5253f7e6a49ed8c50257bb", + "00000000013107aa587bcf12ac445330ff0325d73c5253f7e6a49ed8c50257bb", 0 - ], + ], [ - "00000000090ff53d49c9ffd51511af8d5cba2038a8e25e3b17186b1bc941f43d", + "00000000090ff53d49c9ffd51511af8d5cba2038a8e25e3b17186b1bc941f43d", 0 - ], + ], [ - "000000000d9e704d5607f77f8983cc56069571a3761d5bd5da55f05ec5d8e844", + "000000000d9e704d5607f77f8983cc56069571a3761d5bd5da55f05ec5d8e844", 0 - ], + ], [ - "0000000002b2b4c0950fb6390f0ae860840e84eb0a82e5e8a9bc37c14bbf43b0", + "0000000002b2b4c0950fb6390f0ae860840e84eb0a82e5e8a9bc37c14bbf43b0", 0 - ], + ], [ - "0000000000be10137a2434dce1d97850b768ce878c1c80ec905f6e9f21e65fa7", + "0000000000be10137a2434dce1d97850b768ce878c1c80ec905f6e9f21e65fa7", 0 - ], + ], [ - "00000000005cd966f80183d4c048e63a5c14f649298dfd261d989d9e3c026bf4", + "00000000005cd966f80183d4c048e63a5c14f649298dfd261d989d9e3c026bf4", 0 - ], + ], [ - "00000000000e8f30e55006a4082380c4b1a372b7ad919d3a9b0a52fe5ee881d3", + "00000000000e8f30e55006a4082380c4b1a372b7ad919d3a9b0a52fe5ee881d3", 0 - ], + ], [ - "0000000000018c70a4c27bdba237ad19ebae5d3ca23f1394ccc746d73669a1c4", + "0000000000018c70a4c27bdba237ad19ebae5d3ca23f1394ccc746d73669a1c4", 0 - ], + ], [ - "0000000000022acc8432c883953227786f7a6560aeaf0176d232c8affa5b25b4", + "0000000000022acc8432c883953227786f7a6560aeaf0176d232c8affa5b25b4", 0 - ], + ], [ - "0000000000001854e95b28b4efcb2cfeb08c76d8cf1fb03f2055b3fb758f3a1c", + "0000000000001854e95b28b4efcb2cfeb08c76d8cf1fb03f2055b3fb758f3a1c", 0 - ], + ], [ - "000000000000187080c2c39f5a3ea8be72ac4d3ec0d16b21cd34f1541bef23be", + "000000000000187080c2c39f5a3ea8be72ac4d3ec0d16b21cd34f1541bef23be", 0 - ], + ], [ - "0000000000001593766a3c63b524f658ec7690df467cc7bbcebbdb56385500d4", + "0000000000001593766a3c63b524f658ec7690df467cc7bbcebbdb56385500d4", 0 - ], + ], [ - "00000000000012d6966dc51a41f2c617192169ec8418405e164ba83b9f7ecdfe", + "00000000000012d6966dc51a41f2c617192169ec8418405e164ba83b9f7ecdfe", 0 - ], + ], [ - "0000000000001d0c7d0a2605e127b00448b71e756ad96625116ab8ca18f74900", + "0000000000001d0c7d0a2605e127b00448b71e756ad96625116ab8ca18f74900", 0 - ], + ], [ - "000000000009cb439ea49282d257595ad1f7602856c16cc26fff423f7783c792", + "000000000009cb439ea49282d257595ad1f7602856c16cc26fff423f7783c792", 0 - ], + ], [ - "0000000000889282b98336c994d7420a639221e0484b511227fd616d78dbd028", + "0000000000889282b98336c994d7420a639221e0484b511227fd616d78dbd028", 0 - ], + ], [ - "000000000071a4a2ad6767864bd21239c74c9912a40ca9fd3b209e21b66460d9", + "000000000071a4a2ad6767864bd21239c74c9912a40ca9fd3b209e21b66460d9", 0 - ], + ], [ - "0000000000f3ed2c3c9a7c3a7291e859cecba8cf9243d23a4892e6be8ea9b70f", + "0000000000f3ed2c3c9a7c3a7291e859cecba8cf9243d23a4892e6be8ea9b70f", 0 - ], + ], [ - "00000000006a4258ffdff8b7f6f4f685ce18c6eb1d7a1cf501ca9e02fcb7620a", + "00000000006a4258ffdff8b7f6f4f685ce18c6eb1d7a1cf501ca9e02fcb7620a", 0 - ], + ], [ - "00000000004af78f1a109d1267a9c24d69c6a4b30fea49f0efa6c8834cf394f9", + "00000000004af78f1a109d1267a9c24d69c6a4b30fea49f0efa6c8834cf394f9", 0 - ], + ], [ - "0000000000193bf3efbb145747198470a81b2cd33c991057676742d5c22a64b2", + "0000000000193bf3efbb145747198470a81b2cd33c991057676742d5c22a64b2", 0 - ], + ], [ - "000000000006b436798c7e4a8c3bdbf054a66707feee5a18ce9ca57eb95bb48a", + "000000000006b436798c7e4a8c3bdbf054a66707feee5a18ce9ca57eb95bb48a", 0 - ], + ], [ - "0000000000001db50c7caa3a02ea4f173343f958f334a8bf3f8638add9e69b34", + "0000000000001db50c7caa3a02ea4f173343f958f334a8bf3f8638add9e69b34", 0 - ], + ], [ - "0000000000003c621629cc0bcec5968d61d2e42c6673de4d46555118ad5001d8", + "0000000000003c621629cc0bcec5968d61d2e42c6673de4d46555118ad5001d8", 0 - ], + ], [ - "0000000000001262bef2918265f6dd4534013a4650444054fb4f5e490c5ed57b", + "0000000000001262bef2918265f6dd4534013a4650444054fb4f5e490c5ed57b", 0 - ], + ], [ - "0000000000000120ceee972d70cc84430006645997c7337976c673bd75cbef2b", + "0000000000000120ceee972d70cc84430006645997c7337976c673bd75cbef2b", 0 - ], + ], [ - "00000000ba16134dc0c418a116b97ad5deccd6bf6e3daa028a8a6a80d7823faf", + "00000000ba16134dc0c418a116b97ad5deccd6bf6e3daa028a8a6a80d7823faf", 0 - ], + ], [ - "00000000a1a00d6d6fe0660e63402a5a7c7248589211594d37fd800456ce84b6", + "00000000a1a00d6d6fe0660e63402a5a7c7248589211594d37fd800456ce84b6", 0 - ], + ], [ - "00000000394766cec78f962c29aaa715b66e3ad34e1f2323dba45e087cb3b395", + "00000000394766cec78f962c29aaa715b66e3ad34e1f2323dba45e087cb3b395", 0 - ], + ], [ - "0000000008b15a3020676f5e084210ecc05f646885eca1cf6a10e9ae9e3995cc", + "0000000008b15a3020676f5e084210ecc05f646885eca1cf6a10e9ae9e3995cc", 0 - ], + ], [ - "0000000002cf7eb98abe784f6e516670a88b9028a6faabfd099a364c2dc5c42b", + "0000000002cf7eb98abe784f6e516670a88b9028a6faabfd099a364c2dc5c42b", 0 - ], + ], [ - "000000000054015fec337a9ee43eea501d2292f031f5bc1f09758d20f5cd3135", + "000000000054015fec337a9ee43eea501d2292f031f5bc1f09758d20f5cd3135", 0 - ], + ], [ - "0000000000068d24d31a9f1192d848155a2f90939627bc456c9a337135a923fa", + "0000000000068d24d31a9f1192d848155a2f90939627bc456c9a337135a923fa", 0 - ], + ], [ - "000000000006262bd09358258edcc455f9ba46b7f9d6e69d0f6b9da89488a4a5", + "000000000006262bd09358258edcc455f9ba46b7f9d6e69d0f6b9da89488a4a5", 0 - ], + ], [ - "000000000002327bf77ae67961463ea98a78dab06c24ac7d58b1727c5f856626", + "000000000002327bf77ae67961463ea98a78dab06c24ac7d58b1727c5f856626", 0 - ], + ], [ - "0000000000006672235c1606fbacd7861b16b267d203b4d687708eeb1fc25e6d", + "0000000000006672235c1606fbacd7861b16b267d203b4d687708eeb1fc25e6d", 0 - ], + ], [ - "000000000000ac0c9a39a47313a8715f125c46d6ea8be8741b99b1db4a8aae47", + "000000000000ac0c9a39a47313a8715f125c46d6ea8be8741b99b1db4a8aae47", 0 - ], + ], [ - "0000000000007e93f6578e7856aae0ecf6341e1312664d9e1d812ff254c37ae6", + "0000000000007e93f6578e7856aae0ecf6341e1312664d9e1d812ff254c37ae6", 0 - ], + ], [ - "0000000000002a980acdb1443926875e7d4a57859b2b45ce3fa92c7716319f62", + "0000000000002a980acdb1443926875e7d4a57859b2b45ce3fa92c7716319f62", 0 - ], + ], [ - "0000000000683bfd82c63514bc58a80daf699a6bcd040bb2a499540baf52463d", + "0000000000683bfd82c63514bc58a80daf699a6bcd040bb2a499540baf52463d", 0 - ], + ], [ - "00000000373e6262928d7a6cac965b294aef35f90b72c85100ef91501775e06a", + "00000000373e6262928d7a6cac965b294aef35f90b72c85100ef91501775e06a", 0 - ], + ], [ - "0000000000f7bc44061b65c62d4d7747138df127dd2a30f583c3ebb66a25c7a4", + "0000000000f7bc44061b65c62d4d7747138df127dd2a30f583c3ebb66a25c7a4", 0 - ], + ], [ - "000000000212a71c38d0e13ab7c5646c949d4b7ca23afedbe351a43b7607043b", + "000000000212a71c38d0e13ab7c5646c949d4b7ca23afedbe351a43b7607043b", 0 - ], + ], [ - "0000000000a836e88f76ee5dcca1e884572f32f4460a3b024280738d76e98ced", + "0000000000a836e88f76ee5dcca1e884572f32f4460a3b024280738d76e98ced", 0 - ], + ], [ - "0000000000413f6c1b1c9841961636bb3290f2410ba0731f3522c4ff3faa2e0e", + "0000000000413f6c1b1c9841961636bb3290f2410ba0731f3522c4ff3faa2e0e", 0 - ], + ], [ - "0000000000082336107412226110ab2a53016d4faad4deec048828507a300248", + "0000000000082336107412226110ab2a53016d4faad4deec048828507a300248", 0 - ], + ], [ - "000000000000a91e7a3f35a23f01621dd051e314da617714991467131808d3bf", + "000000000000a91e7a3f35a23f01621dd051e314da617714991467131808d3bf", 0 - ], + ], [ - "000000000000cd6576950f6f238227c3ba7f62405ed1bf3af4878c6dc1b04635", + "000000000000cd6576950f6f238227c3ba7f62405ed1bf3af4878c6dc1b04635", 0 - ], + ], [ - "0000000000674099e9741e44da03e9531402a2607a19a65660b57470340828db", + "0000000000674099e9741e44da03e9531402a2607a19a65660b57470340828db", 0 - ], + ], [ - "0000000030c4744001ae85f9e6b46ed0664449927b86b8fbf25b22b851d23671", + "0000000030c4744001ae85f9e6b46ed0664449927b86b8fbf25b22b851d23671", 0 - ], + ], [ - "00000000002f5095ad1a12eb9eedf88ce1e7268368461b6b4e10051148f436cb", + "00000000002f5095ad1a12eb9eedf88ce1e7268368461b6b4e10051148f436cb", 0 - ], + ], [ - "000000000057d3e2a77eadb8b9613cb839ab02a96094dd5d0a6d1f09026c3936", + "000000000057d3e2a77eadb8b9613cb839ab02a96094dd5d0a6d1f09026c3936", 0 - ], + ], [ - "00000000004e0a28be887d6ed037cd9102cbbda7d6c9e584ba51f2c2dce96232", + "00000000004e0a28be887d6ed037cd9102cbbda7d6c9e584ba51f2c2dce96232", 0 - ], + ], [ - "0000000000211346d8099f7ecea72481c4cd45591f5e0d7e347725ac2162f142", + "0000000000211346d8099f7ecea72481c4cd45591f5e0d7e347725ac2162f142", 0 - ], + ], [ - "0000000000199ae9fc06c5acee766db6033b86f76c266cadefe1461c611c2198", + "0000000000199ae9fc06c5acee766db6033b86f76c266cadefe1461c611c2198", 0 - ], + ], [ - "00000000004c9e5748558d4f5a75bc824171e3b958152dfd6844330f1e907f8c", + "00000000004c9e5748558d4f5a75bc824171e3b958152dfd6844330f1e907f8c", 0 - ], + ], [ - "0000000000137addf1521361dad1ee007eb9e6dd4eb8441492ebfaa3c240d556", + "0000000000137addf1521361dad1ee007eb9e6dd4eb8441492ebfaa3c240d556", 0 - ], + ], [ - "000000000054d4c77bb7964e5327c35760d87b890ea336aec5ecdeb783350738", + "000000000054d4c77bb7964e5327c35760d87b890ea336aec5ecdeb783350738", 0 - ], + ], [ - "00000000006b7b06d04818e97a4df66164b471912f88d9cd02de4af6c8bbe74f", + "00000000006b7b06d04818e97a4df66164b471912f88d9cd02de4af6c8bbe74f", 0 - ], + ], [ - "0000000000380fa9858e3e90335c061a3776a26bee1e8b6851de33ec63670782", + "0000000000380fa9858e3e90335c061a3776a26bee1e8b6851de33ec63670782", 0 - ], + ], [ - "00000000000842598b03fb79ce7386e9f9181a02dcf1effc8f70d3ff7368ccd5", + "00000000000842598b03fb79ce7386e9f9181a02dcf1effc8f70d3ff7368ccd5", 0 - ], + ], [ - "000000000003d3475edecd733fc7b82432882d9c9f1350a98ef8921b87db4dec", + "000000000003d3475edecd733fc7b82432882d9c9f1350a98ef8921b87db4dec", 0 - ], + ], [ - "00000000000000e330a8d57a38dbcc0b0a5dc7a4210f231b8082b9be5f9e4bce", + "00000000000000e330a8d57a38dbcc0b0a5dc7a4210f231b8082b9be5f9e4bce", 0 - ], + ], [ - "000000000000218ff87fd50cfba2fd04203a78d2600cb2c4dcb039d803426e19", + "000000000000218ff87fd50cfba2fd04203a78d2600cb2c4dcb039d803426e19", 0 - ], + ], [ - "00000000007c96e6e3ed3146260348ac79ea7dc2ec2ae6bf8dc203400a37721d", + "00000000007c96e6e3ed3146260348ac79ea7dc2ec2ae6bf8dc203400a37721d", 0 - ], + ], [ - "000000005abaa10bf7260470c28ba32f1755b4cfd3734aad580681e39a9605a5", + "000000005abaa10bf7260470c28ba32f1755b4cfd3734aad580681e39a9605a5", 0 - ], + ], [ - "00000000005e77c226e6fffccafa56055e68f0ea0a30101e6a243ab9b3e07db0", + "00000000005e77c226e6fffccafa56055e68f0ea0a30101e6a243ab9b3e07db0", 0 - ], + ], [ - "0000000000e989fe27f85b89c1e852d7bc94b09033cc6c8b32fbbbd9383a9ae1", + "0000000000e989fe27f85b89c1e852d7bc94b09033cc6c8b32fbbbd9383a9ae1", 0 - ], + ], [ - "000000000091a1e962438583146293ef34156962445ffc5e81e4d0fe327d37ac", + "000000000091a1e962438583146293ef34156962445ffc5e81e4d0fe327d37ac", 0 - ], + ], [ - "0000000000477978a6903217e2817d10e99bdfedb4f8bc396b96fd5b0b93b522", + "0000000000477978a6903217e2817d10e99bdfedb4f8bc396b96fd5b0b93b522", 0 - ], + ], [ - "00000000000bfd9e5f13a9c03c48e8b58a937cf1ae2849160f1ca11f8fcced3c", + "00000000000bfd9e5f13a9c03c48e8b58a937cf1ae2849160f1ca11f8fcced3c", 0 - ], + ], [ - "00000000000158dd3c31b6379887b4353ef2898c03b7ce55458fcd57cb6f0639", + "00000000000158dd3c31b6379887b4353ef2898c03b7ce55458fcd57cb6f0639", 0 - ], + ], [ - "00000000000029d7009eb56b9d38366005576b82a9b59fc845522a34ad36a38a", + "00000000000029d7009eb56b9d38366005576b82a9b59fc845522a34ad36a38a", 0 - ], + ], [ - "0000000000e6e207a82b8ad7136352204bb8e9ccfcd25885a715d3c65cbee997", + "0000000000e6e207a82b8ad7136352204bb8e9ccfcd25885a715d3c65cbee997", 0 - ], + ], [ - "0000000000fadc4429f50fc534ccac4db5e51a313df25034d6c5c25f7e83448c", + "0000000000fadc4429f50fc534ccac4db5e51a313df25034d6c5c25f7e83448c", 0 - ], + ], [ - "000000000019c58defcfdab6c6ab9497685e61118effda4c2613bf44be19fcbd", + "000000000019c58defcfdab6c6ab9497685e61118effda4c2613bf44be19fcbd", 0 - ], + ], [ - "000000000006cf444d846093c5045d42ddc0986ca805f261476d0fd2eb474c39", + "000000000006cf444d846093c5045d42ddc0986ca805f261476d0fd2eb474c39", 0 - ], + ], [ - "0000000000d0856a3d6a1e5b1ac7e388cc029bd8410b3b1489598974fe470568", + "0000000000d0856a3d6a1e5b1ac7e388cc029bd8410b3b1489598974fe470568", 0 - ], + ], [ - "00000000003d9aae63ed532b78082ca5386211e22410fd24ebd5318d1a4cd1da", + "00000000003d9aae63ed532b78082ca5386211e22410fd24ebd5318d1a4cd1da", 0 - ], + ], [ - "00000000000345003879f86021a6d5e3fe93813246818c145947b7e225691177", + "00000000000345003879f86021a6d5e3fe93813246818c145947b7e225691177", 0 - ], + ], [ - "00000000000175393730cde3e49de7af2b81ae736eee005a9f9c4a1e878c52ec", + "00000000000175393730cde3e49de7af2b81ae736eee005a9f9c4a1e878c52ec", 0 - ], + ], [ - "00000000000087a8c621c879aec2a897258632d6aa631b9a38ba4d564e08682a", + "00000000000087a8c621c879aec2a897258632d6aa631b9a38ba4d564e08682a", 0 - ], + ], [ - "0000000000002ea641b2975935bd9caf337b51ac9f9bb90a54f6ea6ee5d3112b", + "0000000000002ea641b2975935bd9caf337b51ac9f9bb90a54f6ea6ee5d3112b", 0 - ], + ], [ - "0000000000000c544f9b6a8cbab6d25caf949875622bf75139234850b10affe1", + "0000000000000c544f9b6a8cbab6d25caf949875622bf75139234850b10affe1", 0 - ], + ], [ - "0000000000000f66fc4e37232a29f3389c493863a980d58a1d570eddd5268999", + "0000000000000f66fc4e37232a29f3389c493863a980d58a1d570eddd5268999", 0 - ], + ], [ - "00000000001213fe2bbb8aacb1fc14983586e09db964151cb507956a81b35f25", + "00000000001213fe2bbb8aacb1fc14983586e09db964151cb507956a81b35f25", 0 - ], + ], [ - "0000000000ba82c2160602ddc1913bc4c133ad0af8848e014367c84110d00e05", + "0000000000ba82c2160602ddc1913bc4c133ad0af8848e014367c84110d00e05", 0 - ], + ], [ - "0000000000b7a98b364b1cf9521275a915c7a1b3a0f0c052c7d8efb620ec0870", + "0000000000b7a98b364b1cf9521275a915c7a1b3a0f0c052c7d8efb620ec0870", 0 - ], + ], [ - "000000000047dc62db23540ab4aee43e54812aedb623a2a158aa3244fc784722", + "000000000047dc62db23540ab4aee43e54812aedb623a2a158aa3244fc784722", 0 - ], + ], [ - "00000000005291002da10e53c3855882251a6e5a425b5e639ef9be3bd05767ca", + "00000000005291002da10e53c3855882251a6e5a425b5e639ef9be3bd05767ca", 0 - ], + ], [ - "00000000005ffbcbc0d9b380584bdc78050a6f0c3582b4c9c5103a150cbc71f5", + "00000000005ffbcbc0d9b380584bdc78050a6f0c3582b4c9c5103a150cbc71f5", 0 - ], + ], [ - "00000000000a7a69cc06b0a68b27a8fa5d29727ec3b6db8d32d61cf7489b5ff3", + "00000000000a7a69cc06b0a68b27a8fa5d29727ec3b6db8d32d61cf7489b5ff3", 0 - ], + ], [ - "000000000007212eb8c49758d98cefaa6098da2b877a6055be341f5f7c0ad301", + "000000000007212eb8c49758d98cefaa6098da2b877a6055be341f5f7c0ad301", 0 - ], + ], [ - "000000000068d1099d8cf3f43f6d164f2925b1d52ede75640cc65ca020e1de1c", + "000000000068d1099d8cf3f43f6d164f2925b1d52ede75640cc65ca020e1de1c", 0 - ], + ], [ - "0000000008d5ddef4468a4414bd08184c2eba0ec536b85a743b1091828a6a884", + "0000000008d5ddef4468a4414bd08184c2eba0ec536b85a743b1091828a6a884", 0 - ], + ], [ - "000000000acae40db93b589783b0cde70b98552955cb3c12f08de1b417d9008d", + "000000000acae40db93b589783b0cde70b98552955cb3c12f08de1b417d9008d", 0 - ], + ], [ - "000000000066a51eaa3a54036f338719da3d5779180c0bc3787b533410de90e5", + "000000000066a51eaa3a54036f338719da3d5779180c0bc3787b533410de90e5", 0 - ], + ], [ - "00000000008b521677a6e897950aac69640e52efb01b7af10bba3820ecd09a89", + "00000000008b521677a6e897950aac69640e52efb01b7af10bba3820ecd09a89", 0 - ], + ], [ - "00000000001823f0e399311cab0fcf57403e094feebf99b22030bafd2004da87", + "00000000001823f0e399311cab0fcf57403e094feebf99b22030bafd2004da87", 0 - ], + ], [ - "00000000000bf821c2abf5bcd00ca96439ddf5b0b593be5601145fda5338efdc", + "00000000000bf821c2abf5bcd00ca96439ddf5b0b593be5601145fda5338efdc", 0 - ], + ], [ - "000000000003f4fd19b2af0141289177014ecc6dce6ea8fb50bab93d4a291095", + "000000000003f4fd19b2af0141289177014ecc6dce6ea8fb50bab93d4a291095", 0 - ], + ], [ - "00000000000011842d892a02e55ca594caddc9f3cea1979ddffefc070eda8498", + "00000000000011842d892a02e55ca594caddc9f3cea1979ddffefc070eda8498", 0 - ], + ], [ - "000000000000208aa0259d20f51c0e7b8895e18a93aea79af9b3832e710ef134", + "000000000000208aa0259d20f51c0e7b8895e18a93aea79af9b3832e710ef134", 0 - ], + ], [ - "00000000000007218f849e72dee1f7fb6fcf36f3b6745c6468187ed2ed13287f", + "00000000000007218f849e72dee1f7fb6fcf36f3b6745c6468187ed2ed13287f", 0 - ], + ], [ - "00000000000f79f656cae641c2b74554c6ecd673c0c7550671c4c2af940661b3", + "00000000000f79f656cae641c2b74554c6ecd673c0c7550671c4c2af940661b3", 0 - ], + ], [ - "0000000000199b4d178c05fd1c3154c9a4632eadc7bfc734c4522176c977ce8a", + "0000000000199b4d178c05fd1c3154c9a4632eadc7bfc734c4522176c977ce8a", 0 - ], + ], [ - "00000000085d0682d481635cb2e6de2e4d9884589455a86194f0b222f9acb3c6", + "00000000085d0682d481635cb2e6de2e4d9884589455a86194f0b222f9acb3c6", 0 - ], + ], [ - "00000000015972a5a6786a14b009bf582c4bbf7b9854591dd8d26f82b43ddaef", + "00000000015972a5a6786a14b009bf582c4bbf7b9854591dd8d26f82b43ddaef", 0 - ], + ], [ - "000000000064bf72b7bdbfcbe96dbbd0efcaf7aa94c0f92cb4e6662819468fe4", + "000000000064bf72b7bdbfcbe96dbbd0efcaf7aa94c0f92cb4e6662819468fe4", 0 - ], + ], [ - "00000000003df36b7962bb4ad62266c462382eddc93f4bfeac464b95f7a89ee9", + "00000000003df36b7962bb4ad62266c462382eddc93f4bfeac464b95f7a89ee9", 0 - ], + ], [ - "000000000006516d3a9f424eb61db5dfb85aeee29708b78c65d24827bd926263", + "000000000006516d3a9f424eb61db5dfb85aeee29708b78c65d24827bd926263", 0 - ], + ], [ - "000000000001c1709fe1b294712638db356e89155650f6fbecde79ec47a92af7", + "000000000001c1709fe1b294712638db356e89155650f6fbecde79ec47a92af7", 0 - ], + ], [ - "000000000000dfc23251344b593c16c28cd195abcb337519d7bc82175721a033", + "000000000000dfc23251344b593c16c28cd195abcb337519d7bc82175721a033", 0 - ], + ], [ - "0000000000000aae2dd2bf0b8581d137fcfa3d9c4cadbe3ef3834d7cae4268c0", + "0000000000000aae2dd2bf0b8581d137fcfa3d9c4cadbe3ef3834d7cae4268c0", 0 - ], + ], [ - "000000000000092a5baff3d9a5ae87689b2afe668e71bac3b342c7d383f0060f", + "000000000000092a5baff3d9a5ae87689b2afe668e71bac3b342c7d383f0060f", 0 - ], + ], [ - "00000000000fa906eeff7d2e126698d88b8cda01d32ea2c039c26984daaa17a3", + "00000000000fa906eeff7d2e126698d88b8cda01d32ea2c039c26984daaa17a3", 0 - ], + ], [ - "00000000002d4315e5bdc2bcfdb245b914130764a50943a2b2e02ea3acf5c47b", + "00000000002d4315e5bdc2bcfdb245b914130764a50943a2b2e02ea3acf5c47b", 0 - ], + ], [ - "0000000000fc2bc9bb83e04cbe922d64719295bfef6320027725402306bcf1a0", + "0000000000fc2bc9bb83e04cbe922d64719295bfef6320027725402306bcf1a0", 0 - ], + ], [ - "000000000142690e7c334b97612746d6db208e6153bdfa8479d86d1b575feacd", + "000000000142690e7c334b97612746d6db208e6153bdfa8479d86d1b575feacd", 0 - ], + ], [ - "0000000000629a7820e8cdbbed18dcfe16c992152badc745ca73b9b34e53fb0d", + "0000000000629a7820e8cdbbed18dcfe16c992152badc745ca73b9b34e53fb0d", 0 - ], + ], [ - "000000000023c2e9dbf3fe03248e40f4ec3fb2dc81ac573d5a6a4f490c701877", + "000000000023c2e9dbf3fe03248e40f4ec3fb2dc81ac573d5a6a4f490c701877", 0 - ], + ], [ - "000000000013658a43b6d1c4be95fa36e32d3edf80716de3a8f7e98858016adb", + "000000000013658a43b6d1c4be95fa36e32d3edf80716de3a8f7e98858016adb", 0 - ], + ], [ - "000000000007c847295d8c4b6da9d8a64b57c3a2307e64387bf8882b9d35d6de", + "000000000007c847295d8c4b6da9d8a64b57c3a2307e64387bf8882b9d35d6de", 0 - ], + ], [ - "0000000000032bf90b823332af80bd2ea18f411f081c7dca8f2fe79d9215526b", + "0000000000032bf90b823332af80bd2ea18f411f081c7dca8f2fe79d9215526b", 0 - ], + ], [ - "000000000000001bc0655da6f24c6952e811006897a0c6dd8b6bd94f178636c8", + "000000000000001bc0655da6f24c6952e811006897a0c6dd8b6bd94f178636c8", 0 - ], + ], [ - "0000000000001e1d09b15393190cf686e25488db7fcbc2f1ebacc8165fe6e3a0", + "0000000000001e1d09b15393190cf686e25488db7fcbc2f1ebacc8165fe6e3a0", 0 - ], + ], [ - "00000000000cc79ae066badb4157def4067057cefd705bf87f1d832845a7ab36", + "00000000000cc79ae066badb4157def4067057cefd705bf87f1d832845a7ab36", 0 - ], + ], [ - "000000000014408398244b94b4eff6b54875802ede6df2d1d21915333a195719", + "000000000014408398244b94b4eff6b54875802ede6df2d1d21915333a195719", 0 - ], + ], [ - "0000000000114135a1bc757110c05162fa649b694db9569be117e34832c87257", + "0000000000114135a1bc757110c05162fa649b694db9569be117e34832c87257", 0 - ], + ], [ - "00000000009b15fb2bcee1af904989ba0761e4cddc6b3ee214c0bb07dac6211f", + "00000000009b15fb2bcee1af904989ba0761e4cddc6b3ee214c0bb07dac6211f", 0 - ], + ], [ - "000000000012be506dde2c54adf355bdb41a457b0abec436202a3be73f0b052c", + "000000000012be506dde2c54adf355bdb41a457b0abec436202a3be73f0b052c", 0 - ], + ], [ - "00000000000963760ceb5fc65570650d494805e05c9d753f3ea6d44247ad3d08", + "00000000000963760ceb5fc65570650d494805e05c9d753f3ea6d44247ad3d08", 0 - ], + ], [ - "00000000000bfec54977673f68b6fe5f088398e697d778fa7987f8bab6a70825", + "00000000000bfec54977673f68b6fe5f088398e697d778fa7987f8bab6a70825", 0 - ], + ], [ - "000000000000e7f428bb413c17032c0031af0d26133ba93f744a5a0c16cf7e1a", + "000000000000e7f428bb413c17032c0031af0d26133ba93f744a5a0c16cf7e1a", 0 - ], + ], [ - "00000000000036bc80378323c6eaff8ab350b6d89955f602960cb7c93d2feb4c", + "00000000000036bc80378323c6eaff8ab350b6d89955f602960cb7c93d2feb4c", 0 - ], + ], [ - "00000000000f0d5edcaeba823db17f366be49a80d91d15b77747c2e017b8c20a", + "00000000000f0d5edcaeba823db17f366be49a80d91d15b77747c2e017b8c20a", 0 - ], + ], [ - "00000000001ff8fd57798082ab5a7452ada211e1c3be38745155505601498829", + "00000000001ff8fd57798082ab5a7452ada211e1c3be38745155505601498829", 0 - ], + ], [ - "000000000020f960b535eac585e5810ad64f158c1142f0eecd925c8058172933", + "000000000020f960b535eac585e5810ad64f158c1142f0eecd925c8058172933", 0 - ], + ], [ - "0000000000067bd89409368d221507a160e5c45972eeb01efe210054fe8e7d85", + "0000000000067bd89409368d221507a160e5c45972eeb01efe210054fe8e7d85", 0 - ], + ], [ - "00000000003521f2d5ea3232d4835ca6c6bae083ba90458f67d4cd765ce93b09", + "00000000003521f2d5ea3232d4835ca6c6bae083ba90458f67d4cd765ce93b09", 0 - ], + ], [ - "000000000005ab3ff3a0c484eff7b571fb78ce27d93f77a480074232e5ce0c1d", + "000000000005ab3ff3a0c484eff7b571fb78ce27d93f77a480074232e5ce0c1d", 0 - ], + ], [ - "00000000001048c9eca7cc1cbb86946c04498052071f7e7c775bba565ada337c", + "00000000001048c9eca7cc1cbb86946c04498052071f7e7c775bba565ada337c", 0 - ], + ], [ - "00000000000154caacde41be616f924d7d478812148242fba85605eefec9ac61", + "00000000000154caacde41be616f924d7d478812148242fba85605eefec9ac61", 0 - ], + ], [ - "000000000000c34f75bd6f338c0206a31a8d5021cc2ded51e88a6ef4fe686d10", + "000000000000c34f75bd6f338c0206a31a8d5021cc2ded51e88a6ef4fe686d10", 0 - ], + ], [ - "0000000000001e0581d86c49a6ca14ba88639ef908abb09210b57989e06b1a1f", + "0000000000001e0581d86c49a6ca14ba88639ef908abb09210b57989e06b1a1f", 0 - ], + ], [ - "0000000000d0e6dc0bf830b50bde3e400e16ec4f772f92a55390e62d4aa73af3", + "0000000000d0e6dc0bf830b50bde3e400e16ec4f772f92a55390e62d4aa73af3", 0 - ], + ], [ - "00000000069c2501a2f32cc69af72a602ff674438ae04dd05516f72a71b9ab26", + "00000000069c2501a2f32cc69af72a602ff674438ae04dd05516f72a71b9ab26", 0 - ], + ], [ - "0000000000c926b38954550c9b8d363ff058c2eb135eebdb3e640cfa67df803d", + "0000000000c926b38954550c9b8d363ff058c2eb135eebdb3e640cfa67df803d", 0 - ], + ], [ - "000000000011e9ad9c18e9e2095c3662af5be1e918dff653758583aa45dc8197", + "000000000011e9ad9c18e9e2095c3662af5be1e918dff653758583aa45dc8197", 0 - ], + ], [ - "0000000000f311624ff4dcdf07400d0d2fec8b16b14c1c16babc377a2d85ad21", + "0000000000f311624ff4dcdf07400d0d2fec8b16b14c1c16babc377a2d85ad21", 0 - ], + ], [ - "00000000002e455cabfdc2a8955e8ddfe717b12efe5b80937b0c0ad6ac977fc5", + "00000000002e455cabfdc2a8955e8ddfe717b12efe5b80937b0c0ad6ac977fc5", 0 - ], + ], [ - "00000000000fed8889a22339b340f599ac7908e790bfc3cfca9b78078a52d228", + "00000000000fed8889a22339b340f599ac7908e790bfc3cfca9b78078a52d228", 0 - ], + ], [ - "0000000000012ca4492956b3f859b00e5db14b54d422cd95c68c7150743db365", + "0000000000012ca4492956b3f859b00e5db14b54d422cd95c68c7150743db365", 0 - ], + ], [ - "0000000000004c58e8f7bac59eb4a036764a4d8e0da51c0290858ab14fb72481", + "0000000000004c58e8f7bac59eb4a036764a4d8e0da51c0290858ab14fb72481", 0 - ], + ], [ - "0000000000002f60bc99563ff5b4b800c176fe8bde95e8f968fd6b53d74c9cef", + "0000000000002f60bc99563ff5b4b800c176fe8bde95e8f968fd6b53d74c9cef", 0 - ], + ], [ - "0000000000000bffd10a3fb0b5b86d8b2561f39d07f8a4c41dfa08e3e49b7db5", + "0000000000000bffd10a3fb0b5b86d8b2561f39d07f8a4c41dfa08e3e49b7db5", 0 - ], + ], [ - "00000000000006a296be9cd8fd4e3145c146863adbe08b71831abb8a869d032c", + "00000000000006a296be9cd8fd4e3145c146863adbe08b71831abb8a869d032c", 0 - ], + ], [ - "0000000000000c557f496e82891039ff22e277bd604be6e2e8b95e519bee91f9", + "0000000000000c557f496e82891039ff22e277bd604be6e2e8b95e519bee91f9", 0 - ], + ], [ - "0000000000399b30d2111c4bf3051c1f7f2f35bba7ff290d92393341ae47df55", + "0000000000399b30d2111c4bf3051c1f7f2f35bba7ff290d92393341ae47df55", 0 - ], + ], [ - "000000001f88733439e4e8d3c474504aed62037faa16f3845b4c671f69732e26", + "000000001f88733439e4e8d3c474504aed62037faa16f3845b4c671f69732e26", 0 - ], + ], [ - "0000000018aa2f93d2ab76a7e2f1bf5b565b4a1b0ececb6ee46490984f6c0d4b", + "0000000018aa2f93d2ab76a7e2f1bf5b565b4a1b0ececb6ee46490984f6c0d4b", 0 - ], + ], [ - "0000000005e22674fcf65ce7be896a0557205ab26d1f76d73a717f5f14a6d6ad", + "0000000005e22674fcf65ce7be896a0557205ab26d1f76d73a717f5f14a6d6ad", 0 - ], + ], [ - "0000000000223d866b324c097973210f8fc715c9535908359d61d8e1ab2f0100", + "0000000000223d866b324c097973210f8fc715c9535908359d61d8e1ab2f0100", 0 - ], + ], [ - "00000000002b321fd6452ab43849bd7a781953ec4485554e0fdc579f2a52c90a", + "00000000002b321fd6452ab43849bd7a781953ec4485554e0fdc579f2a52c90a", 0 - ], + ], [ - "0000000000173132748c51b5754b0341232325bd118455bf3c8d25164d3eb92a", + "0000000000173132748c51b5754b0341232325bd118455bf3c8d25164d3eb92a", 0 - ], + ], [ - "00000000000143158cdea5fbb9453bbe1a7a900e6feba1e2193e4f5c106d9fba", + "00000000000143158cdea5fbb9453bbe1a7a900e6feba1e2193e4f5c106d9fba", 0 - ], + ], [ - "0000000000014677751456af5630025b3d9921a4eafb4d36a06498f0c6a84c56", + "0000000000014677751456af5630025b3d9921a4eafb4d36a06498f0c6a84c56", 0 - ], + ], [ - "000000000000243976cf2d30ecd3cb1fd0b805fba4da92d2758f78e1c6f8ae92", + "000000000000243976cf2d30ecd3cb1fd0b805fba4da92d2758f78e1c6f8ae92", 0 - ], + ], [ - "0000000000001323db1ab3f247bcb1e92592004b43e4bed0966ed09f675cf269", + "0000000000001323db1ab3f247bcb1e92592004b43e4bed0966ed09f675cf269", 0 - ], + ], [ - "000000000000017a410c22c4b6caf710f5ccf005d644caf276ea8626a538798d", + "000000000000017a410c22c4b6caf710f5ccf005d644caf276ea8626a538798d", 0 - ], + ], [ - "0000000000170b2b1374e3a0dfdce2fbc5e302e1e0e9fb419dc057c9959902d1", + "0000000000170b2b1374e3a0dfdce2fbc5e302e1e0e9fb419dc057c9959902d1", 0 - ], + ], [ - "000000000015b4fad4d929630487680cda2d3aada138c58cc08241ef6dd4ab09", + "000000000015b4fad4d929630487680cda2d3aada138c58cc08241ef6dd4ab09", 0 - ], + ], [ - "00000000000abebab869f1620843d413a3d9e06dc7d9f5201a414d547ace1f99", + "00000000000abebab869f1620843d413a3d9e06dc7d9f5201a414d547ace1f99", 0 - ], + ], [ - "00000000000b0bdaf05c2fe8b12ebd2372f49d8eabcfbccdadd68b5e5b7c9565", + "00000000000b0bdaf05c2fe8b12ebd2372f49d8eabcfbccdadd68b5e5b7c9565", 0 - ], + ], [ - "00000000000ca1af42ee1be2c8895d94f39dab5fcdbe0b4b4065f4be534e7294", + "00000000000ca1af42ee1be2c8895d94f39dab5fcdbe0b4b4065f4be534e7294", 0 - ], + ], [ - "000000000069d0cc8c0452bf86cff87db05232f801a162acab2d080d6e4e9ea9", + "000000000069d0cc8c0452bf86cff87db05232f801a162acab2d080d6e4e9ea9", 0 - ], + ], [ - "000000000019c7f7685f5bdc3afbb5e978cb3f4f70fea7b2b410139741303b53", + "000000000019c7f7685f5bdc3afbb5e978cb3f4f70fea7b2b410139741303b53", 0 - ], + ], [ - "00000000000d3874ce21db78f4d1883ad9ae8b26c1d7c13f3d723ff85629d595", + "00000000000d3874ce21db78f4d1883ad9ae8b26c1d7c13f3d723ff85629d595", 0 - ], + ], [ - "0000000000033f87c25275ff72b58630d8da90221f2c84bcbd77c8e615709f8b", + "0000000000033f87c25275ff72b58630d8da90221f2c84bcbd77c8e615709f8b", 0 - ], + ], [ - "000000000000dc72adaaae6483eb6737de7d21b3a24b2426330e80b078ceaed1", + "000000000000dc72adaaae6483eb6737de7d21b3a24b2426330e80b078ceaed1", 0 - ], + ], [ - "00000000000002fb1337228db02ac464565271f22f045c1b6ee5e449f057a829", + "00000000000002fb1337228db02ac464565271f22f045c1b6ee5e449f057a829", 0 - ], + ], [ - "00000000000001902376ff640d3088899af0819dbd15f602156a13ac2fc8e94e", + "00000000000001902376ff640d3088899af0819dbd15f602156a13ac2fc8e94e", 0 - ], + ], [ - "000000000000007ee49761a1c8284a3b8acefa39e37e455be4773d648e2db794", + "000000000000007ee49761a1c8284a3b8acefa39e37e455be4773d648e2db794", 0 - ], + ], [ - "00000000000005b4d495a77f57018dbc72bf47993d494349329a3c653f04ab93", + "00000000000005b4d495a77f57018dbc72bf47993d494349329a3c653f04ab93", 0 - ], + ], [ - "000000000000009dcb3ae6d68828e2f5ccfd58780abb260354e74484106f81ce", + "000000000000009dcb3ae6d68828e2f5ccfd58780abb260354e74484106f81ce", 0 - ], + ], [ - "00000000a3ceb118021fb42d39be52db951c6f852bb9a241046e972706f7329a", + "00000000a3ceb118021fb42d39be52db951c6f852bb9a241046e972706f7329a", 0 - ], + ], [ - "00000000574e8e1c27fa54c77b4e7cd1b79de070f0d3ad5b383206ab9777d983", + "00000000574e8e1c27fa54c77b4e7cd1b79de070f0d3ad5b383206ab9777d983", 0 - ], + ], [ - "0000000039d562f640c1743421d53e7e04c3e8ba222c339fff6f3d25b1d4a7fe", + "0000000039d562f640c1743421d53e7e04c3e8ba222c339fff6f3d25b1d4a7fe", 0 - ], + ], [ - "000000000001cb1559d55c697871e18d5c26800f77fb11587241bfbec3b15e26", + "000000000001cb1559d55c697871e18d5c26800f77fb11587241bfbec3b15e26", 0 - ], + ], [ - "000000000006e01a93090319756c7ca826ef655feb0cc2ef9abcc59d67de5e5b", + "000000000006e01a93090319756c7ca826ef655feb0cc2ef9abcc59d67de5e5b", 0 - ], + ], [ - "000000000000a81aaf5a4c013032638a077af6aad8bc449d74daef8ad3a74419", + "000000000000a81aaf5a4c013032638a077af6aad8bc449d74daef8ad3a74419", 0 - ], + ], [ - "00000000000087d0574963c1582f2161298e2de5e48f74566291ef9afc2be24a", + "00000000000087d0574963c1582f2161298e2de5e48f74566291ef9afc2be24a", 0 - ], + ], [ - "0000000000033251e71c347cd663945fb68efe82a8c6666c0b41e93f1c46658d", + "0000000000033251e71c347cd663945fb68efe82a8c6666c0b41e93f1c46658d", 0 - ], + ], [ - "000000000000f592857e6f0e4711b5b93fdf95f2b21a5963bde15be750a07908", + "000000000000f592857e6f0e4711b5b93fdf95f2b21a5963bde15be750a07908", 0 - ], + ], [ - "0000000000004353c8426e18b942a5012934ddac8322b86d6ab98ed7c0ee86ed", + "0000000000004353c8426e18b942a5012934ddac8322b86d6ab98ed7c0ee86ed", 0 - ], + ], [ - "00000000004f027845b699f42e7d0d30c530e99524c5f97186ce6a250a5fac42", + "00000000004f027845b699f42e7d0d30c530e99524c5f97186ce6a250a5fac42", 0 - ], + ], [ - "000000002fc6407edc060df90785082834867331e6746a43ed34a26fbdc5df64", + "000000002fc6407edc060df90785082834867331e6746a43ed34a26fbdc5df64", 0 - ], + ], [ - "0000000000048733007c91ea3665bd4e1653b10799e3f43abee0fe830ffbb3ad", + "0000000000048733007c91ea3665bd4e1653b10799e3f43abee0fe830ffbb3ad", 0 - ], + ], [ - "0000000000025a9b1c5afceba0c78c4b0320797acdc1ad50b4e040f148fbff7f", + "0000000000025a9b1c5afceba0c78c4b0320797acdc1ad50b4e040f148fbff7f", 0 - ], + ], [ - "00000000007ca6d026d27387edc1c5570de41c61bacbcb1dad2c0f300b49e637", + "00000000007ca6d026d27387edc1c5570de41c61bacbcb1dad2c0f300b49e637", 0 - ], + ], [ - "00000000000258f683a77ad509da82a4fab24188fdb4b4690e212c50794a9abb", + "00000000000258f683a77ad509da82a4fab24188fdb4b4690e212c50794a9abb", 0 - ], + ], [ - "0000000000015111bce7b6ac13c930484e14e31e13e43355cb4d63c8f1782440", + "0000000000015111bce7b6ac13c930484e14e31e13e43355cb4d63c8f1782440", 0 - ], + ], [ - "000000000001ca074fdecac7749d95f28f10c83a7e13787fd865bfbe505382bc", + "000000000001ca074fdecac7749d95f28f10c83a7e13787fd865bfbe505382bc", 0 - ], + ], [ - "0000000000001c11a6505dd44ab405fdc07ddfc015f3c1166a5d9352ab58b52c", + "0000000000001c11a6505dd44ab405fdc07ddfc015f3c1166a5d9352ab58b52c", 0 - ], + ], [ - "0000000000000c83f7f8e1cab4efa08d6c68c4555fb6ab542e01b87edd8f56ac", + "0000000000000c83f7f8e1cab4efa08d6c68c4555fb6ab542e01b87edd8f56ac", 0 - ], + ], [ - "00000000000009561d0ceba15388573d2a994aff24512ec3ed7d7881aa0997dd", + "00000000000009561d0ceba15388573d2a994aff24512ec3ed7d7881aa0997dd", 0 - ], + ], [ - "00000000007dc7cfbbb94db1fbc076a70a1252fd595686b4d75b2ea77ed6ee9e", + "00000000007dc7cfbbb94db1fbc076a70a1252fd595686b4d75b2ea77ed6ee9e", 0 - ], + ], [ - "00000000000251feb68a8c90852f73aeb29ebda191038737b7edd37c9475f4ac", + "00000000000251feb68a8c90852f73aeb29ebda191038737b7edd37c9475f4ac", 0 - ], + ], [ - "0000000000013f9a97045ea9047654e514951288911b2c3986787c27bab49106", + "0000000000013f9a97045ea9047654e514951288911b2c3986787c27bab49106", 0 - ], + ], [ - "0000000006e8c37735c61f22bec69f4cb7eba03172349e7012b7704652f3e83a", + "0000000006e8c37735c61f22bec69f4cb7eba03172349e7012b7704652f3e83a", 0 - ], + ], [ - "0000000001f341add5657043d8e50e53ba079fe24966a2668f904be5579c84b9", + "0000000001f341add5657043d8e50e53ba079fe24966a2668f904be5579c84b9", 0 - ], + ], [ - "000000000029a6275cd477d77939424bd183c2f1308a9912f45aa7cc9ed13b56", + "000000000029a6275cd477d77939424bd183c2f1308a9912f45aa7cc9ed13b56", 0 - ], + ], [ - "00000000000a0336239e5e1faedf5bd2eedf38c9a5ba34a832356aea70aeb102", + "00000000000a0336239e5e1faedf5bd2eedf38c9a5ba34a832356aea70aeb102", 0 - ], + ], [ - "000000000003c1a2b25093a64eb624055f6a3a26e18b8e7ea2d9382ec7a3609a", + "000000000003c1a2b25093a64eb624055f6a3a26e18b8e7ea2d9382ec7a3609a", 0 - ], + ], [ - "000000000001bd89bf7e8740ce22adfa6e8793bd1716a647e558ed1742ee8329", + "000000000001bd89bf7e8740ce22adfa6e8793bd1716a647e558ed1742ee8329", 0 - ], + ], [ - "0000000000001320421f1bb2c94000e11a621f581fc277c0e2911c3b89f680bd", + "0000000000001320421f1bb2c94000e11a621f581fc277c0e2911c3b89f680bd", 0 - ], + ], [ - "000000000054ce90a949f5ae2d43c4ace599668c6ccbc50620f6d5705922ea7c", + "000000000054ce90a949f5ae2d43c4ace599668c6ccbc50620f6d5705922ea7c", 0 - ], + ], [ - "00000000200d16fea4857e6b73169cc593421a57971acdbcaf87a31d7d8d72c8", + "00000000200d16fea4857e6b73169cc593421a57971acdbcaf87a31d7d8d72c8", 0 - ], + ], [ - "0000000000e75602181c88f713b91c49de291ed878be305d25b75c0ec5fbe942", + "0000000000e75602181c88f713b91c49de291ed878be305d25b75c0ec5fbe942", 0 - ], + ], [ - "000000000081f8169c3c3665f20351dc0fe499612ae232ec0b55858a8e5dc6e9", + "000000000081f8169c3c3665f20351dc0fe499612ae232ec0b55858a8e5dc6e9", 0 - ], + ], [ - "0000000000d7ad232e7593fb435d125343b8113bbdb3705ab58ac0e18c26cc79", + "0000000000d7ad232e7593fb435d125343b8113bbdb3705ab58ac0e18c26cc79", 0 - ], + ], [ - "0000000000076df615d887e33193ca2dc0f2fc0e70744512c95da6242e9b1a81", + "0000000000076df615d887e33193ca2dc0f2fc0e70744512c95da6242e9b1a81", 0 - ], + ], [ - "0000000000084a62093d1929843e74456686429b698a7ea9b1901c1565779f58", + "0000000000084a62093d1929843e74456686429b698a7ea9b1901c1565779f58", 0 - ], + ], [ - "00000000000251d1da01e9de9fcaf3ca3a64bff78a5faf51a8e697dfab6b5e4b", + "00000000000251d1da01e9de9fcaf3ca3a64bff78a5faf51a8e697dfab6b5e4b", 0 - ], + ], [ - "000000000000609a8798996b1f1fe0b66060a628eadc380d0d369a2318c2d0ec", + "000000000000609a8798996b1f1fe0b66060a628eadc380d0d369a2318c2d0ec", 0 - ], + ], [ - "00000000000014770aeab044a022e86d888a6ede75b6474022c71aead3a1db74", + "00000000000014770aeab044a022e86d888a6ede75b6474022c71aead3a1db74", 0 - ], + ], [ - "00000000000004101d04ebc90ade5d4b911aa13c038ecf25e9887d877203ddb8", + "00000000000004101d04ebc90ade5d4b911aa13c038ecf25e9887d877203ddb8", 0 - ], + ], [ - "000000007c700410b61eb7ff1aaccbfc3a79e4e4484ad7a2b0eda4d91dc4b613", + "000000007c700410b61eb7ff1aaccbfc3a79e4e4484ad7a2b0eda4d91dc4b613", 0 - ], + ], [ - "00000000055ff438a031413ee042fd3c0a2b69be98690542806ff123b7988024", + "00000000055ff438a031413ee042fd3c0a2b69be98690542806ff123b7988024", 0 - ], + ], [ - "000000002eca5f9f2c3b656d2550662fdee4c95da133eade51a5cae653bc69fe", + "000000002eca5f9f2c3b656d2550662fdee4c95da133eade51a5cae653bc69fe", 0 - ], + ], [ - "000000000c679b76ccf0c5b943095fdee8fa466311edbea2c4a05f9430ffef3f", + "000000000c679b76ccf0c5b943095fdee8fa466311edbea2c4a05f9430ffef3f", 0 - ], + ], [ - "00000000007c6f494e32d5d9de58fa008a770fdc0a7b4a141be5b7c2de3ab970", + "00000000007c6f494e32d5d9de58fa008a770fdc0a7b4a141be5b7c2de3ab970", 0 - ], + ], [ - "0000000000d5dcd5a26c8ad29c1293e70401e2f90d8288469df3816b8cc6d4aa", + "0000000000d5dcd5a26c8ad29c1293e70401e2f90d8288469df3816b8cc6d4aa", 0 - ], + ], [ - "00000000000d754d94f36cacbfb620710672afb1558499cabe17ca62c54a7d3a", + "00000000000d754d94f36cacbfb620710672afb1558499cabe17ca62c54a7d3a", 0 - ], + ], [ - "000000000004096bb78fba714b130f7f1f929e2803c75a7a85619f7a2b86567f", + "000000000004096bb78fba714b130f7f1f929e2803c75a7a85619f7a2b86567f", 0 - ], + ], [ - "0000000000020e686c38d44c35896df35f9f1b7723a82a826a5e2393c25ef68c", + "0000000000020e686c38d44c35896df35f9f1b7723a82a826a5e2393c25ef68c", 0 - ], + ], [ - "000000000000504f9af6885c0cb6484109ea205a956c8efae9557a1f5b9233da", + "000000000000504f9af6885c0cb6484109ea205a956c8efae9557a1f5b9233da", 0 - ], + ], [ - "0000000000000e8746e52e4320ec17e66434a3936a3825f7046fe874e92275fb", + "0000000000000e8746e52e4320ec17e66434a3936a3825f7046fe874e92275fb", 0 - ], + ], [ - "0000000000000f48d818a9a026270c9f733f629959bea25192596d59874b1ce2", + "0000000000000f48d818a9a026270c9f733f629959bea25192596d59874b1ce2", 0 - ], + ], [ - "00000000eaa9214cb05b241828a1cfb0c4209fb7ea64429815d61f7c1d98939e", + "00000000eaa9214cb05b241828a1cfb0c4209fb7ea64429815d61f7c1d98939e", 0 - ], + ], [ - "000000001f7f915a6002cce4edd5cba392307f3a199a520ee8937327a9135162", + "000000001f7f915a6002cce4edd5cba392307f3a199a520ee8937327a9135162", 0 - ], + ], [ - "0000000009674ee0c606d687bdcddf8e023462927e2902b3381bc4bb862a7397", + "0000000009674ee0c606d687bdcddf8e023462927e2902b3381bc4bb862a7397", 0 - ], + ], [ - "0000000001f3f3528c083a4b11eb2f04d8bbeca92b57f05d8282909bde78bc77", + "0000000001f3f3528c083a4b11eb2f04d8bbeca92b57f05d8282909bde78bc77", 0 - ], + ], [ - "000000000131917ac459aefb91774dbb42caeca497afc0cfd1766e0338cc7f88", + "000000000131917ac459aefb91774dbb42caeca497afc0cfd1766e0338cc7f88", 0 - ], + ], [ - "000000000027634444081e1289354cb50034a506bb306a2ac1d8280683771c5c", + "000000000027634444081e1289354cb50034a506bb306a2ac1d8280683771c5c", 0 - ], + ], [ - "000000000017a852acff78fbee573329d45bb8b121e9f6fc1e4f687bb3778ada", + "000000000017a852acff78fbee573329d45bb8b121e9f6fc1e4f687bb3778ada", 0 - ], + ], [ - "000000000006789e1a00eca982fb2827f680b254c4a0ecb005af4464f3585a02", + "000000000006789e1a00eca982fb2827f680b254c4a0ecb005af4464f3585a02", 0 - ], + ], [ - "0000000000015d2e9f54b1e9419d6b32ce68ae626cdd7f2a1954f22ca39ae0fa", + "0000000000015d2e9f54b1e9419d6b32ce68ae626cdd7f2a1954f22ca39ae0fa", 0 - ], + ], [ - "0000000000002f7893bc169165ed9fefb434b6201103f23cc84a747a68ff8797", + "0000000000002f7893bc169165ed9fefb434b6201103f23cc84a747a68ff8797", 0 - ], + ], [ - "00000000000008471ccf356a18dd48aa12506ef0b6162cb8f98a8d8bb0465902", + "00000000000008471ccf356a18dd48aa12506ef0b6162cb8f98a8d8bb0465902", 0 - ], + ], [ - "0000000000000596f00b9db53c4111bcde16f3781471c5307af1a996e34ec20a", + "0000000000000596f00b9db53c4111bcde16f3781471c5307af1a996e34ec20a", 0 - ], + ], [ - "000000000000007b5d2406f64f5f5833c063a6906552e815e603140c00bca951", + "000000000000007b5d2406f64f5f5833c063a6906552e815e603140c00bca951", 0 - ], + ], [ - "0000000093ca5d935740a1b25f10ce092fd777c2bb521f3156619389ae78931e", + "0000000093ca5d935740a1b25f10ce092fd777c2bb521f3156619389ae78931e", 0 - ], + ], [ - "00000000292f3a48559527341f72400a0f8a783aebcaae5bfa0e390dfaa5286b", + "00000000292f3a48559527341f72400a0f8a783aebcaae5bfa0e390dfaa5286b", 0 - ], + ], [ - "000000001e852ed7ddf0108d1fce0f4f686f43c8c1b85bcb12c43e564dc7630e", + "000000001e852ed7ddf0108d1fce0f4f686f43c8c1b85bcb12c43e564dc7630e", 0 - ], + ], [ - "000000000c4bea8fb1e7f3a1f3e6c6b3f71388c0ec7eef3de381853767e89f87", + "000000000c4bea8fb1e7f3a1f3e6c6b3f71388c0ec7eef3de381853767e89f87", 0 - ], + ], [ - "00000000029ef31a21711b55c4300efa38ace0b706091e373f48285286f2c578", + "00000000029ef31a21711b55c4300efa38ace0b706091e373f48285286f2c578", 0 - ], + ], [ - "0000000000979060786bb008f193d3917e28667bb1b28329f3adadc172e4cce7", + "0000000000979060786bb008f193d3917e28667bb1b28329f3adadc172e4cce7", 0 - ], + ], [ - "000000000019030ceb98013b1627517b45b04ee055ef445813bbebaa25fa1ed3", + "000000000019030ceb98013b1627517b45b04ee055ef445813bbebaa25fa1ed3", 0 - ], + ], [ - "00000000000adf202247bb794fc9a3c82cd8767143f1e6ed5f60940ee18b09a8", + "00000000000adf202247bb794fc9a3c82cd8767143f1e6ed5f60940ee18b09a8", 0 - ], + ], [ - "000000000000b19061e2481d8be6183b3d881b0d58601072d2a32729435f6af3", + "000000000000b19061e2481d8be6183b3d881b0d58601072d2a32729435f6af3", 0 - ], + ], [ - "0000000000007a6d34f59b29e8d4da53e51e3414acd18527466d064945fe19fc", + "0000000000007a6d34f59b29e8d4da53e51e3414acd18527466d064945fe19fc", 0 - ], + ], [ - "0000000000002e66ca213a2c3e9eb5fa62de29feb83880a0bd29f90fca8ad199", + "0000000000002e66ca213a2c3e9eb5fa62de29feb83880a0bd29f90fca8ad199", 0 - ], + ], [ - "0000000000000b4ca10aa100728d0928f37db5296303db1b74ffe29e4a17b6cd", + "0000000000000b4ca10aa100728d0928f37db5296303db1b74ffe29e4a17b6cd", 0 - ], + ], [ - "0000000000000143309f6b19567955743775f61f8dc6932c0b46cf5fb11c6c72", + "0000000000000143309f6b19567955743775f61f8dc6932c0b46cf5fb11c6c72", 0 - ], + ], [ - "00000000000000b04d5409b3ac60cc18c0b9a3d58b303594635a8f75a9d2abd5", + "00000000000000b04d5409b3ac60cc18c0b9a3d58b303594635a8f75a9d2abd5", 0 - ], + ], [ - "000000000000040a2699f62a552703a278608248c2ce823f4cd8845376e9a371", + "000000000000040a2699f62a552703a278608248c2ce823f4cd8845376e9a371", 0 - ], + ], [ - "00000000000005cfcb850db7e83d4963994f958bae9b1de1483f5aeb3d449925", + "00000000000005cfcb850db7e83d4963994f958bae9b1de1483f5aeb3d449925", 0 - ], + ], [ - "00000000000190f80220e70c1481153671a7c90fd856988c183ab0e3d9313df8", + "00000000000190f80220e70c1481153671a7c90fd856988c183ab0e3d9313df8", 0 - ], + ], [ - "000000009374563a06178641d06776f66554c2a094b5319f0801fe35cef72ccf", + "000000009374563a06178641d06776f66554c2a094b5319f0801fe35cef72ccf", 0 - ], + ], [ - "00000000003e4e6e5e8e4a89e7de50eed104d4a49d2992ff101b6740beec7cb5", + "00000000003e4e6e5e8e4a89e7de50eed104d4a49d2992ff101b6740beec7cb5", 0 - ], + ], [ - "0000000000618cd377d14aaa441cbdb92527894f98da316eca81664f8ab5488d", + "0000000000618cd377d14aaa441cbdb92527894f98da316eca81664f8ab5488d", 0 - ], + ], [ - "00000000000d977ab2897885fee712f58612fce8c10ffbe9400326fe3429b77b", + "00000000000d977ab2897885fee712f58612fce8c10ffbe9400326fe3429b77b", 0 - ], + ], [ - "00000000000c3575b487dd0f938c5bc744fa65ca4ca3a9c981b8bda903ec110b", + "00000000000c3575b487dd0f938c5bc744fa65ca4ca3a9c981b8bda903ec110b", 0 - ], + ], [ - "0000000000247ac689595ed8d62678bfe53e5af13c0f5455e558f5e6bb375c16", + "0000000000247ac689595ed8d62678bfe53e5af13c0f5455e558f5e6bb375c16", 0 - ], + ], [ - "0000000000093d175376aa621176511f335a48f824b66d998e8082f85134a48b", + "0000000000093d175376aa621176511f335a48f824b66d998e8082f85134a48b", 0 - ], + ], [ - "000000000000c0c0448fe922f2c737946297d35f2c25ad7cc223e11bbe58e1f8", + "000000000000c0c0448fe922f2c737946297d35f2c25ad7cc223e11bbe58e1f8", 0 - ], + ], [ - "00000000000016abe4e7c10ddb658bb089b2ef3b1de3f3329097cf679eedf2b5", + "00000000000016abe4e7c10ddb658bb089b2ef3b1de3f3329097cf679eedf2b5", 0 - ], + ], [ - "000000000000242757cea5b68c52b83dd8c2eb9257492074fc69dfa30bd4cbf4", + "000000000000242757cea5b68c52b83dd8c2eb9257492074fc69dfa30bd4cbf4", 0 - ], + ], [ - "00000000000006813f3dd7726a509fbe3101835db155dfd35d44aeae6aedb316", + "00000000000006813f3dd7726a509fbe3101835db155dfd35d44aeae6aedb316", 0 - ], + ], [ - "000000000000053cc4f39cff1c8cee1aff7e289a85dee84164d2d981afc8f17a", + "000000000000053cc4f39cff1c8cee1aff7e289a85dee84164d2d981afc8f17a", 0 - ], + ], [ - "00000000000000789724805cf1d37ef689acf52c47a460507f540d5e5ca79bfa", + "00000000000000789724805cf1d37ef689acf52c47a460507f540d5e5ca79bfa", 0 - ], + ], [ - "00000000000003d71618bb8952887f65540270a5e54d6246b9419e08831b5e4e", + "00000000000003d71618bb8952887f65540270a5e54d6246b9419e08831b5e4e", 0 - ], + ], [ - "0000000000000251a513a33eadfad67c015f6e3b291dfd0ae1cc4bb3a43006dc", + "0000000000000251a513a33eadfad67c015f6e3b291dfd0ae1cc4bb3a43006dc", 0 - ], + ], [ - "00000000968009e3f8d6e6071e7def68298307717a9af6c2d44986deaae297d5", + "00000000968009e3f8d6e6071e7def68298307717a9af6c2d44986deaae297d5", 0 - ], + ], [ - "0000000062bcacb734df83bbfa3e1b9a8dfa570ecffb6c29eaaf8e9498cccd30", + "0000000062bcacb734df83bbfa3e1b9a8dfa570ecffb6c29eaaf8e9498cccd30", 0 - ], + ], [ - "000000001d4618c0931bd3c25ee592c35341f30ff3b549a671f637b3c26ef414", + "000000001d4618c0931bd3c25ee592c35341f30ff3b549a671f637b3c26ef414", 0 - ], + ], [ - "000000000418b329df96a004f1b652ad06a7ca295f9f2e711c412d00493f5a86", + "000000000418b329df96a004f1b652ad06a7ca295f9f2e711c412d00493f5a86", 0 - ], + ], [ - "000000000302bfb88e9027237d023c4b969e106c9a7a23a84103776de7880836", + "000000000302bfb88e9027237d023c4b969e106c9a7a23a84103776de7880836", 0 - ], + ], [ - "000000000069b9f7d9134fd93c8b7e3af8b26bbcbb5553af02fb6ed644d7fca5", + "000000000069b9f7d9134fd93c8b7e3af8b26bbcbb5553af02fb6ed644d7fca5", 0 - ], + ], [ - "00000000000411ec444240ee91e2777ad18b80dee854e3e838e32209e84774fa", + "00000000000411ec444240ee91e2777ad18b80dee854e3e838e32209e84774fa", 0 - ], + ], [ - "0000000000007c73f322eba4dee5463305227c7e1a8139f1b7b296444f265052", + "0000000000007c73f322eba4dee5463305227c7e1a8139f1b7b296444f265052", 0 - ], + ], [ - "00000000000129adf0f9c0242aedbb9d87935d67ee4ddea758c00344d4b6a29e", + "00000000000129adf0f9c0242aedbb9d87935d67ee4ddea758c00344d4b6a29e", 0 - ], + ], [ - "000000000000343594e671158b6e1b4b6499f6ad66e2aeabf1f6d295d3dba850", + "000000000000343594e671158b6e1b4b6499f6ad66e2aeabf1f6d295d3dba850", 0 - ], + ], [ - "000000000000320f0d5c22ba22b588b97a0e02273034bcd53669b1c8c4eeda1b", + "000000000000320f0d5c22ba22b588b97a0e02273034bcd53669b1c8c4eeda1b", 0 - ], + ], [ - "0000000000001e8cdb2d98471a5c60bdbddbe644b9ad08e17a97b3a7dce1e332", + "0000000000001e8cdb2d98471a5c60bdbddbe644b9ad08e17a97b3a7dce1e332", 0 - ], + ], [ - "0000000000000026c9994ccdd027e86f51a2e36812f754bd855a7f9b1ca56511", + "0000000000000026c9994ccdd027e86f51a2e36812f754bd855a7f9b1ca56511", 0 - ], + ], [ - "00000000000002746a820a2c08b35b8d0493c4b5d468fcc971b9c88003e84849", + "00000000000002746a820a2c08b35b8d0493c4b5d468fcc971b9c88003e84849", 0 - ], + ], [ - "000000000002949f844e92645df73ce9c093e5aac0d962a0fa13eb076eec835c", + "000000000002949f844e92645df73ce9c093e5aac0d962a0fa13eb076eec835c", 0 - ], + ], [ - "00000000000156fbda67468ae2863993b98a41227c420246e4bc4e68c84df0e8", + "00000000000156fbda67468ae2863993b98a41227c420246e4bc4e68c84df0e8", 0 - ], + ], [ - "000000000003b43c6c807122c8dd10e2a0cffbf72946f41c97c1ab82d416f74d", + "000000000003b43c6c807122c8dd10e2a0cffbf72946f41c97c1ab82d416f74d", 0 - ], + ], [ - "000000000004e0635c2438b1b649007e5d424b3de846299a8db53049ebf4da0c", + "000000000004e0635c2438b1b649007e5d424b3de846299a8db53049ebf4da0c", 0 - ], + ], [ - "00000000000258e4b79e3cca2ab7d12b35ba77fc491572f2e794f0a10f5236d9", + "00000000000258e4b79e3cca2ab7d12b35ba77fc491572f2e794f0a10f5236d9", 0 - ], + ], [ - "0000000000f5816875d9fece105e499b0467b8fb23ea973c48d828a235acdebd", + "0000000000f5816875d9fece105e499b0467b8fb23ea973c48d828a235acdebd", 0 - ], + ], [ - "000000000001353bbaec810af7a4c74b4964ae072361c0889ed6d59cf16db6fd", + "000000000001353bbaec810af7a4c74b4964ae072361c0889ed6d59cf16db6fd", 0 - ], + ], [ - "00000000000b354d8c389473670ca6bed7e3dffa069f270d35ec9dad810af141", + "00000000000b354d8c389473670ca6bed7e3dffa069f270d35ec9dad810af141", 0 - ], + ], [ - "000000000002fa1f39e7cd8730fa08085ba2b532146ad1ef3b400a13e835ca36", + "000000000002fa1f39e7cd8730fa08085ba2b532146ad1ef3b400a13e835ca36", 0 - ], + ], [ - "000000000000d2c7943eee59652a9783bff27e474a92ec206c5c6e3cdd58d0d7", + "000000000000d2c7943eee59652a9783bff27e474a92ec206c5c6e3cdd58d0d7", 0 - ], + ], [ - "00000000000036034181b4d9a84a97490b49fbee4262b9cfb25a7bfc9c0eec9f", + "00000000000036034181b4d9a84a97490b49fbee4262b9cfb25a7bfc9c0eec9f", 0 - ], + ], [ - "00000000000007deb59381cce692f152fc902732d96a7e7d463bc83915b37c0a", + "00000000000007deb59381cce692f152fc902732d96a7e7d463bc83915b37c0a", 0 - ], + ], [ - "00000000ea7d32833462c0f72ade0cae4766e6065caa4e510331929c56d16632", + "00000000ea7d32833462c0f72ade0cae4766e6065caa4e510331929c56d16632", 0 - ], + ], [ - "000000000068fce0ddd370d4c8f9129a7bc7843e75fc57666202d3b90239e269", + "000000000068fce0ddd370d4c8f9129a7bc7843e75fc57666202d3b90239e269", 0 - ], + ], [ - "0000000026b4a2212c9c9493f8bd9d5331cab6d8eda8ee017410e58a783ca069", + "0000000026b4a2212c9c9493f8bd9d5331cab6d8eda8ee017410e58a783ca069", 0 - ], + ], [ - "0000000009535ea2dc7e83c31cd17f1db1bb78b0a678fc0610844273de143bf5", + "0000000009535ea2dc7e83c31cd17f1db1bb78b0a678fc0610844273de143bf5", 0 - ], + ], [ - "00000000008607cbd5baca91d5b8b82ee965aace335744a3e21578af22bee8ba", + "00000000008607cbd5baca91d5b8b82ee965aace335744a3e21578af22bee8ba", 0 - ], + ], [ - "000000000030dcedae0f5e98c4e176f9569ce76c4d4135bb028fc3144ef381d9", + "000000000030dcedae0f5e98c4e176f9569ce76c4d4135bb028fc3144ef381d9", 0 - ], + ], [ - "0000000000297c3f0e3fa85731222ba934a955bf513247a72a33c74c498cadbe", + "0000000000297c3f0e3fa85731222ba934a955bf513247a72a33c74c498cadbe", 0 - ], + ], [ - "0000000000020a0d4a1e8120cbdb486e758b58919c9df12e0edc8ca1f2795e94", + "0000000000020a0d4a1e8120cbdb486e758b58919c9df12e0edc8ca1f2795e94", 0 - ], + ], [ - "000000000000078773afc9023182bfb6534a60158672e6bc6e8aa5052854da80", + "000000000000078773afc9023182bfb6534a60158672e6bc6e8aa5052854da80", 0 - ], + ], [ - "00000000000102ecdd67800807d9e137357805b9bbf8a439ed86bde5b19fbeb7", + "00000000000102ecdd67800807d9e137357805b9bbf8a439ed86bde5b19fbeb7", 0 - ], + ], [ - "0000000000005c3d2e3c7ee737c67ab465533acb233e0df902c1525fc11c3a55", + "0000000000005c3d2e3c7ee737c67ab465533acb233e0df902c1525fc11c3a55", 0 - ], + ], [ - "0000000000001a77771650cdbbceff87caa4461391ba6a4ddc9815b5b0ab47b0", + "0000000000001a77771650cdbbceff87caa4461391ba6a4ddc9815b5b0ab47b0", 0 - ], + ], [ - "000000000000071ec390bbd28fa2a84e52ab5b32901d0723d22646b04ae01dc3", + "000000000000071ec390bbd28fa2a84e52ab5b32901d0723d22646b04ae01dc3", 0 - ], + ], [ - "00000000000005c3ec3194f710c6f26ee736d59cc935ddfa574440f39846433a", + "00000000000005c3ec3194f710c6f26ee736d59cc935ddfa574440f39846433a", 0 - ], + ], [ - "00000000000001cc3df6924591939269d61ead563b9eb68402a2ca01d7ff99e2", + "00000000000001cc3df6924591939269d61ead563b9eb68402a2ca01d7ff99e2", 0 - ], + ], [ - "000000008c778b3554ceaf3a13a856acbfe46b5750fb86fd92ba30651c2852f4", + "000000008c778b3554ceaf3a13a856acbfe46b5750fb86fd92ba30651c2852f4", 0 - ], + ], [ - "00000000107ca31f75f8ea76073dda3c33330b2706c1ec20c3ec240e853b65c5", + "00000000107ca31f75f8ea76073dda3c33330b2706c1ec20c3ec240e853b65c5", 0 - ], + ], [ - "0000000006ba99b08e7f2869ce113e2ad7464891de7b4cfa96f330d706a2da46", + "0000000006ba99b08e7f2869ce113e2ad7464891de7b4cfa96f330d706a2da46", 0 - ], + ], [ - "000000000f31036bd51b2818f6dfb90ada9be5019abf55fb15694b181e269865", + "000000000f31036bd51b2818f6dfb90ada9be5019abf55fb15694b181e269865", 0 - ], + ], [ - "00000000004fcc101bc47eb7a379b9f608d5c00ac04d2d0ea165ae2937070796", + "00000000004fcc101bc47eb7a379b9f608d5c00ac04d2d0ea165ae2937070796", 0 - ], + ], [ - "000000000044d5ca3eda838edef0df7e69e1934047f8482822ce58ff7a18466d", + "000000000044d5ca3eda838edef0df7e69e1934047f8482822ce58ff7a18466d", 0 - ], + ], [ - "000000000029bdfb157be6d400c4dd3370d98afdd8cd3db6f1ada8c19bbf4650", + "000000000029bdfb157be6d400c4dd3370d98afdd8cd3db6f1ada8c19bbf4650", 0 - ], + ], [ - "000000000005e9699ad8035caa4f73af781ac2040c87b8aa77459b3607209aa8", + "000000000005e9699ad8035caa4f73af781ac2040c87b8aa77459b3607209aa8", 0 - ], + ], [ - "000000000001c0ba033f7d85beeaa167c9bde0e192240653a7ff6d9b81679842", + "000000000001c0ba033f7d85beeaa167c9bde0e192240653a7ff6d9b81679842", 0 - ], + ], [ - "0000000000000e0176111f29e800b49c7b8c7226dbbf4df715f1a4f06bcaaa49", + "0000000000000e0176111f29e800b49c7b8c7226dbbf4df715f1a4f06bcaaa49", 0 - ], + ], [ - "00000000ac3bb2cf42192e9053f5384355228a2b3d70b4ece4d45773a5d5ddd2", + "00000000ac3bb2cf42192e9053f5384355228a2b3d70b4ece4d45773a5d5ddd2", 0 - ], + ], [ - "000000000f29f7b60842b1044b2db7998e9bcbd92f8ec6fe8d159c6d582f1f1a", + "000000000f29f7b60842b1044b2db7998e9bcbd92f8ec6fe8d159c6d582f1f1a", 0 - ], + ], [ - "00000000352f86bc5f9760961a25de009940508bb2cd0b37f378fbc87dc97eef", + "00000000352f86bc5f9760961a25de009940508bb2cd0b37f378fbc87dc97eef", 0 - ], + ], [ - "000000000e9b3086008679ed57f59857f64c3954368ba1088117dbf88d5839cd", + "000000000e9b3086008679ed57f59857f64c3954368ba1088117dbf88d5839cd", 0 - ], + ], [ - "000000000015324bd8fed0e61b62bd1d6c663b862cb98ea03c494a92e4a8d0af", + "000000000015324bd8fed0e61b62bd1d6c663b862cb98ea03c494a92e4a8d0af", 0 - ], + ], [ - "000000000020475a181b7a084b341860a72fc0c1fdfcc13a85adeb0471444b0f", + "000000000020475a181b7a084b341860a72fc0c1fdfcc13a85adeb0471444b0f", 0 - ], + ], [ - "0000000000031905c508a975707b74f24e733880382775ee0e6250666473e1d8", + "0000000000031905c508a975707b74f24e733880382775ee0e6250666473e1d8", 0 - ], + ], [ - "000000000000ca38b15d2ea33a6eef505a9c661540a18882f79ba9a3c575a9bd", + "000000000000ca38b15d2ea33a6eef505a9c661540a18882f79ba9a3c575a9bd", 0 - ], + ], [ - "000000000002739979a7a89fa279303b6606885e750b19e91ed637d7f222b392", + "000000000002739979a7a89fa279303b6606885e750b19e91ed637d7f222b392", 0 - ], + ], [ - "00000000000091e935fc266facc2c92759d5468a39aee5be6b76b519a9bc7567", + "00000000000091e935fc266facc2c92759d5468a39aee5be6b76b519a9bc7567", 0 - ], + ], [ - "00000000000006e339938254208203b67c3c400f703fc29535fc646699e36e58", + "00000000000006e339938254208203b67c3c400f703fc29535fc646699e36e58", 0 - ], + ], [ - "00000000000008f6f1d1150d77f93a7f1baa24b65ceb471b1825b2e92ca6997c", + "00000000000008f6f1d1150d77f93a7f1baa24b65ceb471b1825b2e92ca6997c", 0 - ], + ], [ - "000000000000004894e1edcc5421dbcec77d47c5c50bf27b2cff3f1c242c9eb3", + "000000000000004894e1edcc5421dbcec77d47c5c50bf27b2cff3f1c242c9eb3", 0 - ], + ], [ - "000000000000054e97fb5e1a8bd7900f7c329385895761aaa40d11b3c75b0c8e", + "000000000000054e97fb5e1a8bd7900f7c329385895761aaa40d11b3c75b0c8e", 0 - ], + ], [ - "0000000000000600f4bcc5a89527eede43d1d3342dc12eee1371ab534b0102dc", + "0000000000000600f4bcc5a89527eede43d1d3342dc12eee1371ab534b0102dc", 0 - ], + ], [ - "00000000d1ad5c3ef8c3bb4610b34c264e4ca1ea51c4c8bac18b215e7dc96948", + "00000000d1ad5c3ef8c3bb4610b34c264e4ca1ea51c4c8bac18b215e7dc96948", 0 - ], + ], [ - "0000000062f6a07ae11f9724b8ba9dc2b7348ffd02b59edd3cd2bf387fab9723", + "0000000062f6a07ae11f9724b8ba9dc2b7348ffd02b59edd3cd2bf387fab9723", 0 - ], + ], [ - "000000000014e4c97c9b09ff20203213f3336b0927fd19d214cef1f544756e39", + "000000000014e4c97c9b09ff20203213f3336b0927fd19d214cef1f544756e39", 0 - ], + ], [ - "0000000000d004681880e127aed3fa73255a2e75c2e5c8580cd555526614b294", + "0000000000d004681880e127aed3fa73255a2e75c2e5c8580cd555526614b294", 0 - ], + ], [ - "000000000008093189bba28d40662d6964afc1c0fc9b5c1681bbe32e8bee6c0b", + "000000000008093189bba28d40662d6964afc1c0fc9b5c1681bbe32e8bee6c0b", 0 - ], + ], [ - "00000000002df10cf8165b2204ef4db6721c8c2119d60463b040fbc81c266bbf", + "00000000002df10cf8165b2204ef4db6721c8c2119d60463b040fbc81c266bbf", 0 - ], + ], [ - "00000000000c28c789e7cd9800b98c1dd32e2dda54048116ff47ed856a14acfb", + "00000000000c28c789e7cd9800b98c1dd32e2dda54048116ff47ed856a14acfb", 0 - ], + ], [ - "000000000003e8e7755d9b8299b28c71d9f0e18909f25bc9f3eeec3464ece1dd", + "000000000003e8e7755d9b8299b28c71d9f0e18909f25bc9f3eeec3464ece1dd", 0 - ], + ], [ - "0000000000004b95a0103abe2cb97806caca76f6922d9c5df003cf4a467df822", + "0000000000004b95a0103abe2cb97806caca76f6922d9c5df003cf4a467df822", 0 - ], + ], [ - "0000000000005f12d2ab72bfa715860444c281265ef77e09dc2d041ce89506c0", + "0000000000005f12d2ab72bfa715860444c281265ef77e09dc2d041ce89506c0", 0 - ], + ], [ - "00000000000016eeedb3f367daaee93334188db877fb01cd0282b990f60812b3", + "00000000000016eeedb3f367daaee93334188db877fb01cd0282b990f60812b3", 0 - ], + ], [ - "00000000000001daf3bd8306b6f6899af8aa656d87ac2aa37d493fdcb0cb3000", + "00000000000001daf3bd8306b6f6899af8aa656d87ac2aa37d493fdcb0cb3000", 0 - ], + ], [ - "0000000000000390b86892ad0bed9b520783056961cad7362ace8049aa00471c", + "0000000000000390b86892ad0bed9b520783056961cad7362ace8049aa00471c", 0 - ], + ], [ - "00000000000002105d01b4de7d3e3ada9c757a239151d50b5dd193e3951a23cc", + "00000000000002105d01b4de7d3e3ada9c757a239151d50b5dd193e3951a23cc", 0 - ], + ], [ - "00000000000002362fa802df308201a4b1fff2fd8a91892915a46f5d54098ff4", + "00000000000002362fa802df308201a4b1fff2fd8a91892915a46f5d54098ff4", 0 - ], + ], [ - "00000000000004fb8aa6c6aecb64b9d8d7e691a6cd56fad69fc5278b9e8d98cb", + "00000000000004fb8aa6c6aecb64b9d8d7e691a6cd56fad69fc5278b9e8d98cb", 0 - ], + ], [ - "00000000000000ce3bd9752b2508ddae1ee71332e905163a3c0d7e10b8c472f7", + "00000000000000ce3bd9752b2508ddae1ee71332e905163a3c0d7e10b8c472f7", 0 - ], + ], [ - "00000000000002d0d8520982f15a45d4a405334c61886b6d13d95843386af647", + "00000000000002d0d8520982f15a45d4a405334c61886b6d13d95843386af647", 0 - ], + ], [ - "00000000cafd25502ad67d5d409edfc98f5bbd3173e86e085c69658d58da5f70", + "00000000cafd25502ad67d5d409edfc98f5bbd3173e86e085c69658d58da5f70", 0 - ], + ], [ - "00000000b01e0675317a29a07731ea092fa029016a40ed8bb4fc17cde50eda05", + "00000000b01e0675317a29a07731ea092fa029016a40ed8bb4fc17cde50eda05", 0 - ], + ], [ - "000000002676805396ed2883ccc8ad401aa0a974627559fbae2416ba5c54999c", + "000000002676805396ed2883ccc8ad401aa0a974627559fbae2416ba5c54999c", 0 - ], + ], [ - "0000000000030ab759158f3d425824228dc5c91f32db91d404bee29ee3a41878", + "0000000000030ab759158f3d425824228dc5c91f32db91d404bee29ee3a41878", 0 - ], + ], [ - "00000000000da1c8040ec08e7490fb201ca1fb3571f29c0efd3351ae197d3017", + "00000000000da1c8040ec08e7490fb201ca1fb3571f29c0efd3351ae197d3017", 0 - ], + ], [ - "000000000004e3cba890c16ffc7d1c019d4ab88afa39315164e1b08b8e6a9330", + "000000000004e3cba890c16ffc7d1c019d4ab88afa39315164e1b08b8e6a9330", 0 - ], + ], [ - "00000000000bdcfb630b43977be44529e54daa02d199014a0967deac669bd060", + "00000000000bdcfb630b43977be44529e54daa02d199014a0967deac669bd060", 0 - ], + ], [ - "000000000007254038f9c621d6df0d9fbd90b5697e4170cd6090daaf579f3790", + "000000000007254038f9c621d6df0d9fbd90b5697e4170cd6090daaf579f3790", 0 - ], + ], [ - "000000000002263e27ea1cec943632bf469a28b067f0bfde3b9a6b48540981b4", + "000000000002263e27ea1cec943632bf469a28b067f0bfde3b9a6b48540981b4", 0 - ], + ], [ - "000000000000f194a8d17e683d17f222d23a9032f034d4dc4497263fd785dfa0", + "000000000000f194a8d17e683d17f222d23a9032f034d4dc4497263fd785dfa0", 0 - ], + ], [ - "00000000000036e359b7b07044e3cd5b132a3c72501a0f3f9ccde167f5316bba", + "00000000000036e359b7b07044e3cd5b132a3c72501a0f3f9ccde167f5316bba", 0 - ], + ], [ - "0000000000000b10e98a90e0fd1ffbf7d5fc5a76e8e6e960c6fb158711af6f48", + "0000000000000b10e98a90e0fd1ffbf7d5fc5a76e8e6e960c6fb158711af6f48", 0 - ], + ], [ - "0000000000000104e1e4303b8dae78389bb4e6c38f3eb3fe42aec6464bd5c397", + "0000000000000104e1e4303b8dae78389bb4e6c38f3eb3fe42aec6464bd5c397", 0 - ], + ], [ - "00000000000000bde368a635921f5ad25aeb4b784651de24d624cf20c27691c7", + "00000000000000bde368a635921f5ad25aeb4b784651de24d624cf20c27691c7", 0 - ], + ], [ - "0000000081a626a33cff134e7e56dc0f0a67b1735c96256774885d5d095807c0", + "0000000081a626a33cff134e7e56dc0f0a67b1735c96256774885d5d095807c0", 0 - ], + ], [ - "0000000055d357cdf39130eb767f416101e79025515906bea528f43cb6446920", + "0000000055d357cdf39130eb767f416101e79025515906bea528f43cb6446920", 0 - ], + ], [ - "0000000012558b30f9c1a156fd80b02451e8dfcc7fe0350fb4adeeb84951a0a6", + "0000000012558b30f9c1a156fd80b02451e8dfcc7fe0350fb4adeeb84951a0a6", 0 - ], + ], [ - "000000000001a4868924fc7cca0334ffc4dd49c07fb841c1da059a7c219bdf95", + "000000000001a4868924fc7cca0334ffc4dd49c07fb841c1da059a7c219bdf95", 0 - ], + ], [ - "00000000000010086bd2bba88c71b08cfc7e24183d610a2803e6d382049d52c0", + "00000000000010086bd2bba88c71b08cfc7e24183d610a2803e6d382049d52c0", 0 - ], + ], [ - "0000000000018c83992fe05d820b097228de93787e3f59e65cb89ad4c385e364", + "0000000000018c83992fe05d820b097228de93787e3f59e65cb89ad4c385e364", 0 - ], + ], [ - "00000000000023ab80324770ff4c6802d09e5e1e7de78d2a8e64783904d47f19", + "00000000000023ab80324770ff4c6802d09e5e1e7de78d2a8e64783904d47f19", 0 - ], + ], [ - "000000000000287fa294ea557835d8c98bfe94c4d8b18d5b10f1b62d68957113", + "000000000000287fa294ea557835d8c98bfe94c4d8b18d5b10f1b62d68957113", 0 - ], + ], [ - "000000000001d842f5a0dff13820ba1e151fd8c886e28e648a0be41f3a3f1cb3", + "000000000001d842f5a0dff13820ba1e151fd8c886e28e648a0be41f3a3f1cb3", 0 - ], + ], [ - "000000000000906854973b2ec51409f0b78b25b074eef3f0dbb31e1060c07c3d", + "000000000000906854973b2ec51409f0b78b25b074eef3f0dbb31e1060c07c3d", 0 - ], + ], [ - "00000000000009e694e22b97a4757bffef74f0ccd832398b3e815171636e3a85", + "00000000000009e694e22b97a4757bffef74f0ccd832398b3e815171636e3a85", 0 - ], + ], [ - "0000000000000594b95678610bd47671b1142eb575d1c1d4a0073f69a71a3c65", + "0000000000000594b95678610bd47671b1142eb575d1c1d4a0073f69a71a3c65", 0 - ], + ], [ - "00000000000002ac6d5c058c9932f350aeef84f6e334f4e01b40be4db537f8c2", + "00000000000002ac6d5c058c9932f350aeef84f6e334f4e01b40be4db537f8c2", 0 - ], + ], [ - "00000000000000c9a91d8277c58eab3bfda59d3068142dd54216129e5597ccbd", + "00000000000000c9a91d8277c58eab3bfda59d3068142dd54216129e5597ccbd", 0 - ], + ], [ - "0000000000000051bff2f64c9078fb346d6a2a209ba5c3ffa0048c6b7027e47f", + "0000000000000051bff2f64c9078fb346d6a2a209ba5c3ffa0048c6b7027e47f", 0 - ], + ], [ - "000000000000df3c366a105ce9ed82a4917c9e19f0736493894feaba2542c7cd", + "000000000000df3c366a105ce9ed82a4917c9e19f0736493894feaba2542c7cd", 0 - ], + ], [ - "0000000000007c8006959f91675b2dbf6264a1172279c826ae7f561b70e88b12", + "0000000000007c8006959f91675b2dbf6264a1172279c826ae7f561b70e88b12", 0 - ], + ], [ - "0000000000015ab3720de7669e8731c84c392aae3509d937b8d883c304e0ca86", + "0000000000015ab3720de7669e8731c84c392aae3509d937b8d883c304e0ca86", 0 - ], + ], [ - "0000000000016d7156ee43da389020fb5d30f05e11498c54f7e324561d6a6039", + "0000000000016d7156ee43da389020fb5d30f05e11498c54f7e324561d6a6039", 0 - ], + ], [ - "0000000000009c9592f83d63fe39839080ced253e1d71c52bce576f823b7722a", + "0000000000009c9592f83d63fe39839080ced253e1d71c52bce576f823b7722a", 0 - ], + ], [ - "00000000003dee6b438ddf51b831fbedb9d2ee91644aaf5866e3a85c740b3a99", + "00000000003dee6b438ddf51b831fbedb9d2ee91644aaf5866e3a85c740b3a99", 0 - ], + ], [ - "00000000000155f5594d8a3ade605d1504ee9a6f6389f1c4516e974698ebb9e4", + "00000000000155f5594d8a3ade605d1504ee9a6f6389f1c4516e974698ebb9e4", 0 - ], + ], [ - "000000000001e21adfc306bf4aa2ad90e3c2aa4a43263d1bbdc70bf9f1593416", + "000000000001e21adfc306bf4aa2ad90e3c2aa4a43263d1bbdc70bf9f1593416", 0 - ], + ], [ - "0000000000008218e84ba7d9850a5c12b77ec5d1348e7cbdfdcb86f8fe929682", + "0000000000008218e84ba7d9850a5c12b77ec5d1348e7cbdfdcb86f8fe929682", 0 - ], + ], [ - "00000000000054fb41b42b30fff1738104c3edca6dab47c75e4d3565bc4b9e34", + "00000000000054fb41b42b30fff1738104c3edca6dab47c75e4d3565bc4b9e34", 0 - ], + ], [ - "0000000000002763b825c315ba35959dcc1bd8114627949ede769ac2eece8248", + "0000000000002763b825c315ba35959dcc1bd8114627949ede769ac2eece8248", 0 - ], + ], [ - "00000000000007437044da0baed38a28e2991c6a527f495e91739a8d9c35acbb", + "00000000000007437044da0baed38a28e2991c6a527f495e91739a8d9c35acbb", 0 - ], + ], [ - "000000000000032d74ad8eb0a0be6b39b8e095bd9ca8537da93aae15087aafaf", + "000000000000032d74ad8eb0a0be6b39b8e095bd9ca8537da93aae15087aafaf", 0 - ], + ], [ - "000000000000006d4025181f5b54cca6d730cc26313817c6529ba9ed62cc83b3", + "000000000000006d4025181f5b54cca6d730cc26313817c6529ba9ed62cc83b3", 0 - ], + ], [ - "000000001c3ad81ffea0b74d356b6886fd3381506b7c568f96c88a78815ede09", + "000000001c3ad81ffea0b74d356b6886fd3381506b7c568f96c88a78815ede09", 0 - ], + ], [ - "000000000140739d224af1254712d8c4e9fb9082b381baf22c628e459157ce49", + "000000000140739d224af1254712d8c4e9fb9082b381baf22c628e459157ce49", 0 - ], + ], [ - "000000000306491c835f1a03c8d1e17645435296d3593dacba8ab1a7d9341d38", + "000000000306491c835f1a03c8d1e17645435296d3593dacba8ab1a7d9341d38", 0 - ], + ], [ - "000000000002b383618b228eb8e4cfcf269ba647b91ac6d60ddd070295709ad1", + "000000000002b383618b228eb8e4cfcf269ba647b91ac6d60ddd070295709ad1", 0 - ], + ], [ - "000000000000c90fc724a76407b4405032474fc8d1649817f7ad238b96856c6a", + "000000000000c90fc724a76407b4405032474fc8d1649817f7ad238b96856c6a", 0 - ], + ], [ - "0000000000002d5a62b323a5f213152dd84e2f415a3c6c28043c0ccaaddb3229", + "0000000000002d5a62b323a5f213152dd84e2f415a3c6c28043c0ccaaddb3229", 0 - ], + ], [ - "0000000000008c086a21457ba523b682356c760538000a480650cd667a29647a", + "0000000000008c086a21457ba523b682356c760538000a480650cd667a29647a", 0 - ], + ], [ - "00000000000007c586d36266aa83d8cc702aa29f31e3cc01c6eeac5a0f5f9887", + "00000000000007c586d36266aa83d8cc702aa29f31e3cc01c6eeac5a0f5f9887", 0 - ], + ], [ - "0000000000013bf175e35603f24758bf8d40b1f5c266e707e3ba4de6fae43a7f", + "0000000000013bf175e35603f24758bf8d40b1f5c266e707e3ba4de6fae43a7f", 0 - ], + ], [ - "00000000000096841c486983a4333afb2525549abe57e7263723b9782e9cfef1", + "00000000000096841c486983a4333afb2525549abe57e7263723b9782e9cfef1", 0 - ], + ], [ - "00000000000012dfd7c4e1f40a1dd4833da2d010a33fc65c053871884146c941", + "00000000000012dfd7c4e1f40a1dd4833da2d010a33fc65c053871884146c941", 0 - ], + ], [ - "0000000000000b47eb6bc8c6562b5a30cefcf81623a37f6f61cc7497a530eb33", + "0000000000000b47eb6bc8c6562b5a30cefcf81623a37f6f61cc7497a530eb33", 0 - ], + ], [ - "0000000000000021ca4558aeb796f900e581c029d751f89e1a69ae9ba9f6ebb3", + "0000000000000021ca4558aeb796f900e581c029d751f89e1a69ae9ba9f6ebb3", 0 - ], + ], [ - "00000000000000a5bf9029aebb1956200304ffee31bc09f1323ae412d81fa2b2", + "00000000000000a5bf9029aebb1956200304ffee31bc09f1323ae412d81fa2b2", 0 - ], + ], [ - "0000000000000046f38ada53de3346d8191f69c8f3c0ba9e1950f5bf291989c4", + "0000000000000046f38ada53de3346d8191f69c8f3c0ba9e1950f5bf291989c4", 0 - ], + ], [ - "00000000658b5a572ea407ac49a1dccf85d67d0adfc5f613b17fa3fff1d99d51", + "00000000658b5a572ea407ac49a1dccf85d67d0adfc5f613b17fa3fff1d99d51", 0 - ], + ], [ - "000000005d6be9ae758c520b0061feee99cd0a231f982cc074e4d0ced1f96952", + "000000005d6be9ae758c520b0061feee99cd0a231f982cc074e4d0ced1f96952", 0 - ], + ], [ - "0000000001aa4671747707d329a94c398c04aaf2268e551ac5d6a7f29ffd4acd", + "0000000001aa4671747707d329a94c398c04aaf2268e551ac5d6a7f29ffd4acd", 0 - ], + ], [ - "0000000004b441b97963463faca7a933469fabfa3e7b243621159e445e5c192a", + "0000000004b441b97963463faca7a933469fabfa3e7b243621159e445e5c192a", 0 - ], + ], [ - "0000000002ce8842113bc875330fa77f3b984a90806a5ec0bb73321fef3c76c6", + "0000000002ce8842113bc875330fa77f3b984a90806a5ec0bb73321fef3c76c6", 0 - ], + ], [ - "0000000000019761bf9a1c6f679b880e9fb45b3f6dc1accdbdcfce01368c9377", + "0000000000019761bf9a1c6f679b880e9fb45b3f6dc1accdbdcfce01368c9377", 0 - ], + ], [ - "0000000000008a069efd1a7923557be3d9584d307b2555dc0a56d66e74e083e1", + "0000000000008a069efd1a7923557be3d9584d307b2555dc0a56d66e74e083e1", 0 - ], + ], [ - "000000000001c14cec52030659ef7d45318ca574f1633ef69e9c8c9bd7e45289", + "000000000001c14cec52030659ef7d45318ca574f1633ef69e9c8c9bd7e45289", 0 - ], + ], [ - "0000000000009cfccb8a27f66f1d9ff40c9d47449f78d82fee2465daca582ab7", + "0000000000009cfccb8a27f66f1d9ff40c9d47449f78d82fee2465daca582ab7", 0 - ], + ], [ - "0000000000007f30cfae7fbb8ff965f70d500b98be202b1dd57ea418500c922d", + "0000000000007f30cfae7fbb8ff965f70d500b98be202b1dd57ea418500c922d", 0 - ], + ], [ - "0000000000002cbd2dbab4352fe4979e0d5afc47f21ef575ae0e3bb620a5478a", + "0000000000002cbd2dbab4352fe4979e0d5afc47f21ef575ae0e3bb620a5478a", 0 - ], + ], [ - "000000000000017a872a5c7a15b3cb6e1ecf9e009759848b85c19ca6e7bd16d2", + "000000000000017a872a5c7a15b3cb6e1ecf9e009759848b85c19ca6e7bd16d2", 0 - ], + ], [ - "00000000000001ade79216032b49854c966a1061fd3f8c6c56a0d38d0024629e", + "00000000000001ade79216032b49854c966a1061fd3f8c6c56a0d38d0024629e", + 0 + ], + [ + "0000000000000090b8dfe4dde9f9f8d675642db97b3649bd147f60d1fc64cd76", + 0 + ], + [ + "0000000000000109ed5f0d6fc387ad1bc45db1e522f76adce131067fc64440ec", + 0 + ], + [ + "000000000000003105650f0b8e7b4cb466cd32ff5608f59906879aff5cad64a7", + 0 + ], + [ + "0000000000000113d4262419a8aa3a4fe928c0ea81893a2d2ffee5258b2085d8", + 0 + ], + [ + "00000000000000f15b8a196b1c3568d14b5a7856da2fef7a7f5548266582ff28", + 0 + ], + [ + "0000000000000034fb9e91c8b5f7147bd1a4f089d19a266d183df6f8497d1dff", + 0 + ], + [ + "000000000000005e51ad800c9e8ab11abb4b945f5ea86b120fa140c8af6301e0", + 0 + ], + [ + "00000000000000e903f2002fd08a732fd5380ea1f2dac26bb84d57e247af8ac2", + 0 + ], + [ + "000000000015115dac432884296259f508dae6b6f5f15cef17939840f5a295c3", + 0 + ], + [ + "000000000029913c80e5f49d413603d91f5fd67b76a7e187f76c077973be6f8a", + 0 + ], + [ + "00000000002e864e470ccec1fec0ca5f2053c9a9b8978a40f3482b4d30f683a9", + 0 + ], + [ + "00000000001ccf523df85df9abdb7c5bbad5c5fcbd12a4a8eb4700de7291f03b", + 0 + ], + [ + "00000000002aa81027df021e3ccde48dff6e7f01a4aba27727308f2ce17f2f1a", + 0 + ], + [ + "000000000015a577d71d65bde7e8f5359458336218dc024584f7510b38dc1259", + 0 + ], + [ + "00000000003aef1877bcc6817cac497aeb95af3336ba2908e8194f96a2c9fc29", + 0 + ], + [ + "00000000000ccd42d542ddca68300ec2a9db2564327108234641535fd51aa7f3", + 0 + ], + [ + "000000000000a2652b2e523866f3c4d5c07dc1c204d439b627f2ab2848bfa139", + 0 + ], + [ + "0000000000002c065179a394d8da754c2e2db5fed21def076c16c24a902b448d", + 0 + ], + [ + "000000000000175a878558186e53b559e494ce7e9f687bf0462d63169bfcce03", + 0 + ], + [ + "00000000000007524a71cc81cadbd1ddf9d38848fa8081ad2a72eade4b70d1c1", + 0 + ], + [ + "0000000000000159321405d24d99131df6bf69ffeca30c4a949926807c4175ad", + 0 + ], + [ + "000000000000016c271ae44c8dca3567b332ec178a243be2a7dfa7a0aef270c3", + 0 + ], + [ + "00000000000000a7d62de601cdf73e25c49c1c99717c94ffd574fc657fd42fa8", + 0 + ], + [ + "0000000000000052d492170de491c1355d640bae48f4d954009e963f6f9a18c3", + 0 + ], + [ + "000000006f5707f2f707b9ddcce2739723e911210b131da4ca1efdff581212ad", + 0 + ], + [ + "00000000021be68dc9c33db0c2222e97cd2c06fc43834e8f5292133c45c2abb4", + 0 + ], + [ + "00000000019ca3eaf7c39f70a7a1a736f74021abf885bebc5d91aa946496bac5", + 0 + ], + [ + "00000000006e4752fbe2627ebb2d0118f7437908a8219f973324727195335209", + 0 + ], + [ + "00000000038471612a0955307f367071888985707ec0e42c82f9145caed8fea1", + 0 + ], + [ + "000000000004604d2d7d921b21d86f2ade82ded3af33877ec59d47072023d763", + 0 + ], + [ + "000000000034a3e45665a8dcbb94e7a218375a5199b3f3ca2cc7b5fe151bb198", + 0 + ], + [ + "0000000000043fb2c2ff5db60c6d2d35a633746e8585e04a096a9b55a4787fe6", + 0 + ], + [ + "0000000000020d4d8735b66134c1fcdd1d3f3d135b9ff3f70968ef96c227fb75", + 0 + ], + [ + "0000000000004f3f4dc1fa11a6ad9bd320413b042eb599c4599a14d341f6825f", + 0 + ], + [ + "0000000000001e0a495d23acf46a44f8b569ada39ac70730da5e9109871b77e9", + 0 + ], + [ + "00000000000002257a08acca858f239fabb258a7cc1665fc464f6e18e9372d32", + 0 + ], + [ + "00000000000002845d416fbfa05a5d40ba5ba5418a64f06443042a53cf1fd608", + 0 + ], + [ + "00000000000000fee91a2ae8b8d1bb9a687c9b28b0185723c8ff6ffdac2e9ce4", + 0 + ], + [ + "00000000000001d6874b4d88e387098c0b7100ff674d99781fc7045a78216a15", + 0 + ], + [ + "00000000000144a03e701c199673d72fc63766bcf0cdaf565f4c941c7ef72971", + 0 + ], + [ + "000000009b6cc4d8aee22cca6880e4d7bb30bff2851034ad437d63d3a7278de7", + 0 + ], + [ + "0000000023e998d64618475e31b4aee9d83d2bc32cb6d062aa97c0b4651fed08", + 0 + ], + [ + "0000000000036f4bf6b42a7776a97872fa24362064c5bc4bc946acb70ab6fbf4", + 0 + ], + [ + "0000000001e2252455ffd0cf0b4109ace996a0d2a03999f5cc5c5e08fb6130ac", + 0 + ], + [ + "0000000000002713db42d53f0c2d86c904f4e0338652acc1cbda953c530a15bb", + 0 + ], + [ + "000000000001b075f9ccc604a50326732f5d42373c4a831978be0e2d830cac75", + 0 + ], + [ + "0000000000000bfa7d93c6b36298b933b1a652c95ee9f0de4151e007f3180391", + 0 + ], + [ + "000000000002c60a0af1cfeb9c26c60970b354897fd0a94c8e5c414d0767b06b", + 0 + ], + [ + "0000000000001f2d9462507a9408859fb0b5f97013d6b4577337b0382340c5aa", + 0 + ], + [ + "0000000000000b7428e0d3c6c7fd2df623a74125db4989b1c61c78eeed1bcde5", + 0 + ], + [ + "00000000000002e8b4f1fa041a37515c1b76d59994792f1c772c9a4993c194dc", + 0 + ], + [ + "0000000000094e70c0cf5185b480542a1faa8392a3f2f7f583d91e033856d7ce", + 0 + ], + [ + "000000005b036d8c18ed5d1219e4137bd71438c9b1ba7ff4d10a626e9a7bcc98", + 0 + ], + [ + "0000000008745d4a943e958f5cb5084646c0fe1cae57eeab666c3ad0d4ff1dec", + 0 + ], + [ + "00000000000f8c5b3455e540d074b5c71709e37f8950975953798d27bdc701fa", + 0 + ], + [ + "0000000000050885884f7ac233bb174cf7b33c037f81907f7766afe9d0ad9091", + 0 + ], + [ + "000000000002d7cd1043ccd0581a47d6fdf82a7cf1646b61495f917a48ebeb5c", + 0 + ], + [ + "000000000003a2b3e3d7ef47829db1672bfd79e49f32ef3a04ec7c4df355392b", + 0 + ], + [ + "0000000000032a6c7e5bc3878c1815bc6759594a4736638fdacaa5642be3e649", + 0 + ], + [ + "000000000001386a3904f0ba4f25dc7ace09b67a6fe8977e7aecc55813fa9ac5", + 0 + ], + [ + "0000000000003fe030a2231da87076679c1d38d323bf56b45ceb49a5128fb4b1", + 0 + ], + [ + "000000000000147cd3b6195c6a727cd4fe6b3a879d7934e52bf29020ed9c6fcc", 0 ] -] \ No newline at end of file +] + From 5f4a2ebf3e51c643adccaf1a26eb6fa14187702e Mon Sep 17 00:00:00 2001 From: araspitzu Date: Tue, 9 Jul 2019 16:49:55 +0200 Subject: [PATCH 12/12] Wrap all routes in toStrictEntity (#1032) * Wrap all routes in toStrictEntity --- .../scala/fr/acinq/eclair/api/Service.scala | 322 +++++++++--------- 1 file changed, 164 insertions(+), 158 deletions(-) diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/api/Service.scala b/eclair-core/src/main/scala/fr/acinq/eclair/api/Service.scala index e7f2a26e53..3d781cadc5 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/api/Service.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/api/Service.scala @@ -70,6 +70,9 @@ trait Service extends ExtraDirectives with Logging { implicit val actorSystem: ActorSystem implicit val mat: ActorMaterializer + // timeout for reading request parameters from the underlying stream + val paramParsingTimeout = 5 seconds + val apiExceptionHandler = ExceptionHandler { case t: Throwable => logger.error(s"API call failed with cause=${t.getMessage}", t) @@ -125,169 +128,172 @@ trait Service extends ExtraDirectives with Logging { respondWithDefaultHeaders(customHeaders) { handleExceptions(apiExceptionHandler) { handleRejections(apiRejectionHandler) { - formFields("timeoutSeconds".as[Timeout].?) { tm_opt => - // this is the akka timeout - implicit val timeout = tm_opt.getOrElse(Timeout(30 seconds)) - // we ensure that http timeout is greater than akka timeout - withRequestTimeout(timeout.duration + 2.seconds) { - withRequestTimeoutResponse(timeoutResponse) { - authenticateBasicAsync(realm = "Access restricted", userPassAuthenticator) { _ => - post { - path("getinfo") { - complete(eclairApi.getInfoResponse()) - } ~ - path("connect") { - formFields("uri".as[NodeURI]) { uri => - complete(eclairApi.connect(Left(uri))) - } ~ formFields(nodeIdFormParam, "host".as[String], "port".as[Int].?) { (nodeId, host, port_opt) => - complete(eclairApi.connect(Left(NodeURI(nodeId, HostAndPort.fromParts(host, port_opt.getOrElse(NodeURI.DEFAULT_PORT)))))) - } ~ formFields(nodeIdFormParam) { nodeId => - complete(eclairApi.connect(Right(nodeId))) - } + // forcing the request entity to be fully parsed can have performance issues, see: https://doc.akka.io/docs/akka-http/current/routing-dsl/directives/basic-directives/toStrictEntity.html#description + toStrictEntity(paramParsingTimeout) { + formFields("timeoutSeconds".as[Timeout].?) { tm_opt => + // this is the akka timeout + implicit val timeout = tm_opt.getOrElse(Timeout(30 seconds)) + // we ensure that http timeout is greater than akka timeout + withRequestTimeout(timeout.duration + 2.seconds) { + withRequestTimeoutResponse(timeoutResponse) { + authenticateBasicAsync(realm = "Access restricted", userPassAuthenticator) { _ => + post { + path("getinfo") { + complete(eclairApi.getInfoResponse()) } ~ - path("disconnect") { - formFields(nodeIdFormParam) { nodeId => - complete(eclairApi.disconnect(nodeId)) - } - } ~ - path("open") { - formFields(nodeIdFormParam, "fundingSatoshis".as[Long], "pushMsat".as[Long].?, "fundingFeerateSatByte".as[Long].?, "channelFlags".as[Int].?, "openTimeoutSeconds".as[Timeout].?) { - (nodeId, fundingSatoshis, pushMsat, fundingFeerateSatByte, channelFlags, openTimeout_opt) => - complete(eclairApi.open(nodeId, fundingSatoshis, pushMsat, fundingFeerateSatByte, channelFlags, openTimeout_opt)) - } - } ~ - path("updaterelayfee") { - withChannelIdentifier { channelIdentifier => - formFields("feeBaseMsat".as[Long], "feeProportionalMillionths".as[Long]) { (feeBase, feeProportional) => - complete(eclairApi.updateRelayFee(channelIdentifier, feeBase, feeProportional)) + path("connect") { + formFields("uri".as[NodeURI]) { uri => + complete(eclairApi.connect(Left(uri))) + } ~ formFields(nodeIdFormParam, "host".as[String], "port".as[Int].?) { (nodeId, host, port_opt) => + complete(eclairApi.connect(Left(NodeURI(nodeId, HostAndPort.fromParts(host, port_opt.getOrElse(NodeURI.DEFAULT_PORT)))))) + } ~ formFields(nodeIdFormParam) { nodeId => + complete(eclairApi.connect(Right(nodeId))) } - } - } ~ - path("close") { - withChannelIdentifier { channelIdentifier => - formFields("scriptPubKey".as[ByteVector](binaryDataUnmarshaller).?) { scriptPubKey_opt => - complete(eclairApi.close(channelIdentifier, scriptPubKey_opt)) + } ~ + path("disconnect") { + formFields(nodeIdFormParam) { nodeId => + complete(eclairApi.disconnect(nodeId)) } + } ~ + path("open") { + formFields(nodeIdFormParam, "fundingSatoshis".as[Long], "pushMsat".as[Long].?, "fundingFeerateSatByte".as[Long].?, "channelFlags".as[Int].?, "openTimeoutSeconds".as[Timeout].?) { + (nodeId, fundingSatoshis, pushMsat, fundingFeerateSatByte, channelFlags, openTimeout_opt) => + complete(eclairApi.open(nodeId, fundingSatoshis, pushMsat, fundingFeerateSatByte, channelFlags, openTimeout_opt)) + } + } ~ + path("updaterelayfee") { + withChannelIdentifier { channelIdentifier => + formFields("feeBaseMsat".as[Long], "feeProportionalMillionths".as[Long]) { (feeBase, feeProportional) => + complete(eclairApi.updateRelayFee(channelIdentifier, feeBase, feeProportional)) + } + } + } ~ + path("close") { + withChannelIdentifier { channelIdentifier => + formFields("scriptPubKey".as[ByteVector](binaryDataUnmarshaller).?) { scriptPubKey_opt => + complete(eclairApi.close(channelIdentifier, scriptPubKey_opt)) + } + } + } ~ + path("forceclose") { + withChannelIdentifier { channelIdentifier => + complete(eclairApi.forceClose(channelIdentifier)) + } + } ~ + path("peers") { + complete(eclairApi.peersInfo()) + } ~ + path("channels") { + formFields(nodeIdFormParam.?) { toRemoteNodeId_opt => + complete(eclairApi.channelsInfo(toRemoteNodeId_opt)) + } + } ~ + path("channel") { + withChannelIdentifier { channelIdentifier => + complete(eclairApi.channelInfo(channelIdentifier)) + } + } ~ + path("allnodes") { + complete(eclairApi.allNodes()) + } ~ + path("allchannels") { + complete(eclairApi.allChannels()) + } ~ + path("allupdates") { + formFields(nodeIdFormParam.?) { nodeId_opt => + complete(eclairApi.allUpdates(nodeId_opt)) + } + } ~ + path("findroute") { + formFields(invoiceFormParam, amountMsatFormParam.?) { + case (invoice@PaymentRequest(_, Some(amount), _, nodeId, _, _), None) => complete(eclairApi.findRoute(nodeId, amount.toLong, invoice.routingInfo)) + case (invoice, Some(overrideAmount)) => complete(eclairApi.findRoute(invoice.nodeId, overrideAmount, invoice.routingInfo)) + case _ => reject(MalformedFormFieldRejection("invoice", "The invoice must have an amount or you need to specify one using 'amountMsat'")) + } + } ~ + path("findroutetonode") { + formFields(nodeIdFormParam, amountMsatFormParam) { (nodeId, amount) => + complete(eclairApi.findRoute(nodeId, amount)) + } + } ~ + path("parseinvoice") { + formFields(invoiceFormParam) { invoice => + complete(invoice) + } + } ~ + path("payinvoice") { + formFields(invoiceFormParam, amountMsatFormParam.?, "maxAttempts".as[Int].?, "feeThresholdSat".as[Long].?, "maxFeePct".as[Double].?) { + case (invoice@PaymentRequest(_, Some(amount), _, nodeId, _, _), None, maxAttempts, feeThresholdSat_opt, maxFeePct_opt) => + complete(eclairApi.send(nodeId, amount.toLong, invoice.paymentHash, invoice.routingInfo, invoice.minFinalCltvExpiry, maxAttempts, feeThresholdSat_opt, maxFeePct_opt)) + case (invoice, Some(overrideAmount), maxAttempts, feeThresholdSat_opt, maxFeePct_opt) => + complete(eclairApi.send(invoice.nodeId, overrideAmount, invoice.paymentHash, invoice.routingInfo, invoice.minFinalCltvExpiry, maxAttempts, feeThresholdSat_opt, maxFeePct_opt)) + case _ => reject(MalformedFormFieldRejection("invoice", "The invoice must have an amount or you need to specify one using the field 'amountMsat'")) + } + } ~ + path("sendtonode") { + formFields(amountMsatFormParam, paymentHashFormParam, nodeIdFormParam, "maxAttempts".as[Int].?, "feeThresholdSat".as[Long].?, "maxFeePct".as[Double].?) { (amountMsat, paymentHash, nodeId, maxAttempts_opt, feeThresholdSat_opt, maxFeePct_opt) => + complete(eclairApi.send(nodeId, amountMsat, paymentHash, maxAttempts_opt = maxAttempts_opt, feeThresholdSat_opt = feeThresholdSat_opt, maxFeePct_opt = maxFeePct_opt)) + } + } ~ + path("sendtoroute") { + formFields(amountMsatFormParam, paymentHashFormParam, "finalCltvExpiry".as[Long], "route".as[List[PublicKey]](pubkeyListUnmarshaller)) { (amountMsat, paymentHash, finalCltvExpiry, route) => + complete(eclairApi.sendToRoute(route, amountMsat, paymentHash, finalCltvExpiry)) + } + } ~ + path("getsentinfo") { + formFields("id".as[UUID]) { id => + complete(eclairApi.sentInfo(Left(id))) + } ~ formFields(paymentHashFormParam) { paymentHash => + complete(eclairApi.sentInfo(Right(paymentHash))) + } + } ~ + path("createinvoice") { + formFields("description".as[String], amountMsatFormParam.?, "expireIn".as[Long].?, "fallbackAddress".as[String].?, "paymentPreimage".as[ByteVector32](sha256HashUnmarshaller).?) { (desc, amountMsat, expire, fallBackAddress, paymentPreimage_opt) => + complete(eclairApi.receive(desc, amountMsat, expire, fallBackAddress, paymentPreimage_opt)) + } + } ~ + path("getinvoice") { + formFields(paymentHashFormParam) { paymentHash => + completeOrNotFound(eclairApi.getInvoice(paymentHash)) + } + } ~ + path("listinvoices") { + formFields(fromFormParam.?, toFormParam.?) { (from_opt, to_opt) => + complete(eclairApi.allInvoices(from_opt, to_opt)) + } + } ~ + path("listpendinginvoices") { + formFields(fromFormParam.?, toFormParam.?) { (from_opt, to_opt) => + complete(eclairApi.pendingInvoices(from_opt, to_opt)) + } + } ~ + path("getreceivedinfo") { + formFields(paymentHashFormParam) { paymentHash => + completeOrNotFound(eclairApi.receivedInfo(paymentHash)) + } ~ formFields(invoiceFormParam) { invoice => + completeOrNotFound(eclairApi.receivedInfo(invoice.paymentHash)) + } + } ~ + path("audit") { + formFields(fromFormParam.?, toFormParam.?) { (from_opt, to_opt) => + complete(eclairApi.audit(from_opt, to_opt)) + } + } ~ + path("networkfees") { + formFields(fromFormParam.?, toFormParam.?) { (from_opt, to_opt) => + complete(eclairApi.networkFees(from_opt, to_opt)) + } + } ~ + path("channelstats") { + complete(eclairApi.channelStats()) + } ~ + path("usablebalances") { + complete(eclairApi.usableBalances()) } - } ~ - path("forceclose") { - withChannelIdentifier { channelIdentifier => - complete(eclairApi.forceClose(channelIdentifier)) - } - } ~ - path("peers") { - complete(eclairApi.peersInfo()) - } ~ - path("channels") { - formFields(nodeIdFormParam.?) { toRemoteNodeId_opt => - complete(eclairApi.channelsInfo(toRemoteNodeId_opt)) - } - } ~ - path("channel") { - withChannelIdentifier { channelIdentifier => - complete(eclairApi.channelInfo(channelIdentifier)) - } - } ~ - path("allnodes") { - complete(eclairApi.allNodes()) - } ~ - path("allchannels") { - complete(eclairApi.allChannels()) - } ~ - path("allupdates") { - formFields(nodeIdFormParam.?) { nodeId_opt => - complete(eclairApi.allUpdates(nodeId_opt)) - } - } ~ - path("findroute") { - formFields(invoiceFormParam, amountMsatFormParam.?) { - case (invoice@PaymentRequest(_, Some(amount), _, nodeId, _, _), None) => complete(eclairApi.findRoute(nodeId, amount.toLong, invoice.routingInfo)) - case (invoice, Some(overrideAmount)) => complete(eclairApi.findRoute(invoice.nodeId, overrideAmount, invoice.routingInfo)) - case _ => reject(MalformedFormFieldRejection("invoice", "The invoice must have an amount or you need to specify one using 'amountMsat'")) - } - } ~ - path("findroutetonode") { - formFields(nodeIdFormParam, amountMsatFormParam) { (nodeId, amount) => - complete(eclairApi.findRoute(nodeId, amount)) - } - } ~ - path("parseinvoice") { - formFields(invoiceFormParam) { invoice => - complete(invoice) - } - } ~ - path("payinvoice") { - formFields(invoiceFormParam, amountMsatFormParam.?, "maxAttempts".as[Int].?, "feeThresholdSat".as[Long].?, "maxFeePct".as[Double].?) { - case (invoice@PaymentRequest(_, Some(amount), _, nodeId, _, _), None, maxAttempts, feeThresholdSat_opt, maxFeePct_opt) => - complete(eclairApi.send(nodeId, amount.toLong, invoice.paymentHash, invoice.routingInfo, invoice.minFinalCltvExpiry, maxAttempts, feeThresholdSat_opt, maxFeePct_opt)) - case (invoice, Some(overrideAmount), maxAttempts, feeThresholdSat_opt, maxFeePct_opt) => - complete(eclairApi.send(invoice.nodeId, overrideAmount, invoice.paymentHash, invoice.routingInfo, invoice.minFinalCltvExpiry, maxAttempts, feeThresholdSat_opt, maxFeePct_opt)) - case _ => reject(MalformedFormFieldRejection("invoice", "The invoice must have an amount or you need to specify one using the field 'amountMsat'")) - } - } ~ - path("sendtonode") { - formFields(amountMsatFormParam, paymentHashFormParam, nodeIdFormParam, "maxAttempts".as[Int].?, "feeThresholdSat".as[Long].?, "maxFeePct".as[Double].?) { (amountMsat, paymentHash, nodeId, maxAttempts_opt, feeThresholdSat_opt, maxFeePct_opt) => - complete(eclairApi.send(nodeId, amountMsat, paymentHash, maxAttempts_opt = maxAttempts_opt, feeThresholdSat_opt = feeThresholdSat_opt, maxFeePct_opt = maxFeePct_opt)) - } - } ~ - path("sendtoroute") { - formFields(amountMsatFormParam, paymentHashFormParam, "finalCltvExpiry".as[Long], "route".as[List[PublicKey]](pubkeyListUnmarshaller)) { (amountMsat, paymentHash, finalCltvExpiry, route) => - complete(eclairApi.sendToRoute(route, amountMsat, paymentHash, finalCltvExpiry)) - } - } ~ - path("getsentinfo") { - formFields("id".as[UUID]) { id => - complete(eclairApi.sentInfo(Left(id))) - } ~ formFields(paymentHashFormParam) { paymentHash => - complete(eclairApi.sentInfo(Right(paymentHash))) - } - } ~ - path("createinvoice") { - formFields("description".as[String], amountMsatFormParam.?, "expireIn".as[Long].?, "fallbackAddress".as[String].?, "paymentPreimage".as[ByteVector32](sha256HashUnmarshaller).?) { (desc, amountMsat, expire, fallBackAddress, paymentPreimage_opt) => - complete(eclairApi.receive(desc, amountMsat, expire, fallBackAddress, paymentPreimage_opt)) - } - } ~ - path("getinvoice") { - formFields(paymentHashFormParam) { paymentHash => - completeOrNotFound(eclairApi.getInvoice(paymentHash)) - } - } ~ - path("listinvoices") { - formFields(fromFormParam.?, toFormParam.?) { (from_opt, to_opt) => - complete(eclairApi.allInvoices(from_opt, to_opt)) - } - } ~ - path("listpendinginvoices") { - formFields(fromFormParam.?, toFormParam.?) { (from_opt, to_opt) => - complete(eclairApi.pendingInvoices(from_opt, to_opt)) - } - } ~ - path("getreceivedinfo") { - formFields(paymentHashFormParam) { paymentHash => - completeOrNotFound(eclairApi.receivedInfo(paymentHash)) - } ~ formFields(invoiceFormParam) { invoice => - completeOrNotFound(eclairApi.receivedInfo(invoice.paymentHash)) - } - } ~ - path("audit") { - formFields(fromFormParam.?, toFormParam.?) { (from_opt, to_opt) => - complete(eclairApi.audit(from_opt, to_opt)) - } - } ~ - path("networkfees") { - formFields(fromFormParam.?, toFormParam.?) { (from_opt, to_opt) => - complete(eclairApi.networkFees(from_opt, to_opt)) - } - } ~ - path("channelstats") { - complete(eclairApi.channelStats()) - } ~ - path("usablebalances") { - complete(eclairApi.usableBalances()) + } ~ get { + path("ws") { + handleWebSocketMessages(makeSocketHandler) } - } ~ get { - path("ws") { - handleWebSocketMessages(makeSocketHandler) } } }