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. diff --git a/eclair-core/pom.xml b/eclair-core/pom.xml index 22a2320ef2..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-SNAPSHOT + 0.3.2-SNAPSHOT eclair-core_2.11 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 +] + diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/Features.scala b/eclair-core/src/main/scala/fr/acinq/eclair/Features.scala index 2e40b4f4ce..30c8b7ca40 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/Features.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/Features.scala @@ -17,9 +17,7 @@ package fr.acinq.eclair -import java.util.BitSet - -import scodec.bits.ByteVector +import scodec.bits.{BitVector, ByteVector} /** @@ -36,27 +34,34 @@ object Features { val CHANNEL_RANGE_QUERIES_BIT_MANDATORY = 6 val CHANNEL_RANGE_QUERIES_BIT_OPTIONAL = 7 + def apply(hex: String): Features = Features(ByteVector.fromValidHex(hex).toBitVector) +} + +case class Features(localFeatures: BitVector) { + + import Features._ + + def isSet(i: Int) = localFeatures.size > i && localFeatures.get(localFeatures.length - i - 1) - def hasFeature(features: BitSet, bit: Int): Boolean = features.get(bit) + def hasOptionDataLossProtectMandatory = isSet(OPTION_DATA_LOSS_PROTECT_MANDATORY) - def hasFeature(features: ByteVector, bit: Int): Boolean = hasFeature(BitSet.valueOf(features.reverse.toArray), bit) + def hasOptionDataLossProtectOptional = isSet(OPTION_DATA_LOSS_PROTECT_OPTIONAL) + def hasInitialRoutingSync = isSet(INITIAL_ROUTING_SYNC_BIT_OPTIONAL) + + def hasChannelRangeQueriesMandatory = isSet(CHANNEL_RANGE_QUERIES_BIT_MANDATORY) + + def hasChannelRangeQueriesOptional = isSet(CHANNEL_RANGE_QUERIES_BIT_OPTIONAL) /** * Check that the features that we understand are correctly specified, and that there are no mandatory features that * we don't understand (even bits) */ - def areSupported(bitset: BitSet): Boolean = { - val supportedMandatoryFeatures = Set(OPTION_DATA_LOSS_PROTECT_MANDATORY) - for (i <- 0 until bitset.length() by 2) { - if (bitset.get(i) && !supportedMandatoryFeatures.contains(i)) return false + def areSupported: Boolean = { + val supportedMandatoryFeatures = Set(OPTION_DATA_LOSS_PROTECT_MANDATORY, CHANNEL_RANGE_QUERIES_BIT_MANDATORY) + for (i <- 0 until localFeatures.length.toInt by 2) { + if (localFeatures.reverse.get(i) && !supportedMandatoryFeatures.contains(i)) return false } return true } - - /** - * A feature set is supported if all even bits are supported. - * We just ignore unknown odd bits. - */ - def areSupported(features: ByteVector): Boolean = areSupported(BitSet.valueOf(features.reverse.toArray)) } 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) } } } 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/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/io/Peer.scala b/eclair-core/src/main/scala/fr/acinq/eclair/io/Peer.scala index 08969aed8d..3450ffca97 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 @@ -133,26 +133,28 @@ class Peer(val nodeParams: NodeParams, remoteNodeId: PublicKey, authenticator: A when(INITIALIZING) { case Event(remoteInit: wire.Init, d: InitializingData) => d.transport ! TransportHandler.ReadAck(remoteInit) - val remoteHasInitialRoutingSync = Features.hasFeature(remoteInit.localFeatures, Features.INITIAL_ROUTING_SYNC_BIT_OPTIONAL) - val remoteHasChannelRangeQueriesOptional = Features.hasFeature(remoteInit.localFeatures, Features.CHANNEL_RANGE_QUERIES_BIT_OPTIONAL) - val remoteHasChannelRangeQueriesMandatory = Features.hasFeature(remoteInit.localFeatures, Features.CHANNEL_RANGE_QUERIES_BIT_MANDATORY) + val remoteFeatures = Features(ByteVector(remoteInit.localFeatures.toArray).toBitVector) + log.info(s"peer is using globalFeatures=${remoteInit.globalFeatures.toBin} and localFeatures=${remoteInit.localFeatures.toBin}") - log.info(s"$remoteNodeId has features: initialRoutingSync=$remoteHasInitialRoutingSync channelRangeQueriesOptional=$remoteHasChannelRangeQueriesOptional channelRangeQueriesMandatory=$remoteHasChannelRangeQueriesMandatory") - if (Features.areSupported(remoteInit.localFeatures)) { + + if (remoteFeatures.areSupported) { d.origin_opt.foreach(origin => origin ! "connected") - if (remoteHasInitialRoutingSync) { - if (remoteHasChannelRangeQueriesOptional || remoteHasChannelRangeQueriesMandatory) { + if (remoteFeatures.hasInitialRoutingSync) { + if (remoteFeatures.hasChannelRangeQueriesOptional || remoteFeatures.hasChannelRangeQueriesMandatory) { // if they support channel queries we do nothing, they will send us their filters - log.info("{} has set initial routing sync and support channel range queries, we do nothing (they will send us a query)", remoteNodeId) + log.info("peer has set initial routing sync and supports channel range queries, we do nothing (they will send us a query)") } else { // "old" nodes, do as before + log.info("peer requested a full routing table dump") router ! GetRoutingState } } - if (remoteHasChannelRangeQueriesOptional || remoteHasChannelRangeQueriesMandatory) { + + if (remoteFeatures.hasChannelRangeQueriesOptional || remoteFeatures.hasChannelRangeQueriesMandatory) { // if they support channel queries, always ask for their filter - router ! SendChannelQuery(remoteNodeId, d.transport) + // NB: we always add extended info; if peer doesn't understand them it will ignore them + router ! SendChannelQuery(remoteNodeId, d.transport, flags_opt = Some(QueryChannelRangeExtension(QueryChannelRangeExtension.WANT_ALL))) } // let's bring existing/requested channels online 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/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/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/router/ChannelRangeQueries.scala b/eclair-core/src/main/scala/fr/acinq/eclair/router/ChannelRangeQueries.scala deleted file mode 100644 index b2fb131ac2..0000000000 --- a/eclair-core/src/main/scala/fr/acinq/eclair/router/ChannelRangeQueries.scala +++ /dev/null @@ -1,130 +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.router - -import java.io.{ByteArrayInputStream, ByteArrayOutputStream, InputStream} -import java.nio.ByteOrder -import java.util.zip.{DeflaterOutputStream, GZIPInputStream, GZIPOutputStream, InflaterInputStream} - -import fr.acinq.bitcoin.Protocol -import fr.acinq.eclair.ShortChannelId -import scodec.bits.ByteVector - -import scala.annotation.tailrec -import scala.collection.SortedSet - -object ChannelRangeQueries { - - val UNCOMPRESSED_FORMAT = 0.toByte - val ZLIB_FORMAT = 1.toByte - - case class ShortChannelIdsBlock(val firstBlock: Long, val numBlocks: Long, shortChannelIds: ByteVector) - - /** - * Compressed a sequence of *sorted* short channel id. - * - * @param shortChannelIds must be sorted beforehand - * @return a sequence of short channel id blocks - */ - def encodeShortChannelIds(firstBlockIn: Long, numBlocksIn: Long, shortChannelIds: SortedSet[ShortChannelId], format: Byte, useGzip: Boolean = false): List[ShortChannelIdsBlock] = { - if (shortChannelIds.isEmpty) { - // special case: reply with an "empty" block - List(ShortChannelIdsBlock(firstBlockIn, numBlocksIn, ByteVector(0))) - } else { - // LN messages must fit in 65 Kb so we split ids into groups to make sure that the output message will be valid - val count = format match { - case UNCOMPRESSED_FORMAT => 7000 - case ZLIB_FORMAT => 12000 // TODO: do something less simplistic... - } - shortChannelIds.grouped(count).map(ids => { - val (firstBlock, numBlocks) = if (ids.isEmpty) (firstBlockIn, numBlocksIn) else { - val firstBlock: Long = ShortChannelId.coordinates(ids.head).blockHeight - val numBlocks: Long = ShortChannelId.coordinates(ids.last).blockHeight - firstBlock + 1 - (firstBlock, numBlocks) - } - val encoded = encodeShortChannelIdsSingle(ids, format, useGzip) - ShortChannelIdsBlock(firstBlock, numBlocks, encoded) - }).toList - } - } - - def encodeShortChannelIdsSingle(shortChannelIds: Iterable[ShortChannelId], format: Byte, useGzip: Boolean): ByteVector = { - val bos = new ByteArrayOutputStream() - bos.write(format) - format match { - case UNCOMPRESSED_FORMAT => - shortChannelIds.foreach(id => Protocol.writeUInt64(id.toLong, bos, ByteOrder.BIG_ENDIAN)) - case ZLIB_FORMAT => - val output = if (useGzip) new GZIPOutputStream(bos) else new DeflaterOutputStream(bos) - shortChannelIds.foreach(id => Protocol.writeUInt64(id.toLong, output, ByteOrder.BIG_ENDIAN)) - output.finish() - } - ByteVector.view(bos.toByteArray) - } - - /** - * Decompress a zipped sequence of sorted short channel ids. - * - * @param data - * @return a sorted set of short channel ids - */ - def decodeShortChannelIds(data: ByteVector): (Byte, SortedSet[ShortChannelId], Boolean) = { - val format = data.head - if (data.tail.isEmpty) (format, SortedSet.empty[ShortChannelId], false) else { - val buffer = new Array[Byte](8) - - // read 8 bytes from input - // zipped input stream often returns less bytes than what you want to read - @tailrec - def read8(input: InputStream, offset: Int = 0): Int = input.read(buffer, offset, 8 - offset) match { - case len if len <= 0 => len - case 8 => 8 - case len if offset + len == 8 => 8 - case len => read8(input, offset + len) - } - - // read until there's nothing left - @tailrec - def loop(input: InputStream, acc: SortedSet[ShortChannelId]): SortedSet[ShortChannelId] = { - val check = read8(input) - if (check <= 0) acc else loop(input, acc + ShortChannelId(Protocol.uint64(buffer, ByteOrder.BIG_ENDIAN))) - } - - def readAll(useGzip: Boolean) = { - val bis = new ByteArrayInputStream(data.tail.toArray) - val input = format match { - case UNCOMPRESSED_FORMAT => bis - case ZLIB_FORMAT if useGzip => new GZIPInputStream(bis) - case ZLIB_FORMAT => new InflaterInputStream(bis) - } - try { - (format, loop(input, SortedSet.empty[ShortChannelId]), useGzip) - } - finally { - input.close() - } - } - - try { - readAll(useGzip = false) - } - catch { - case _: Throwable if format == ZLIB_FORMAT => readAll(useGzip = true) - } - } - } -} diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/router/Router.scala b/eclair-core/src/main/scala/fr/acinq/eclair/router/Router.scala index 77b70124eb..57dfb9bdcf 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/router/Router.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/router/Router.scala @@ -16,6 +16,8 @@ package fr.acinq.eclair.router +import java.util.zip.CRC32 + import akka.Done import akka.actor.{ActorRef, Props, Status} import akka.event.Logging.MDC @@ -34,6 +36,7 @@ import fr.acinq.eclair.router.Graph.{RichWeight, WeightRatios} import fr.acinq.eclair.transactions.Scripts import fr.acinq.eclair.wire._ import scodec.bits.ByteVector +import shapeless.HNil import scala.collection.immutable.{SortedMap, TreeMap} import scala.collection.{SortedSet, mutable} @@ -73,13 +76,15 @@ case class RouteResponse(hops: Seq[Hop], ignoreNodes: Set[PublicKey], ignoreChan } case class ExcludeChannel(desc: ChannelDesc) // this is used when we get a TemporaryChannelFailure, to give time for the channel to recover (note that exclusions are directed) case class LiftChannelExclusion(desc: ChannelDesc) -case class SendChannelQuery(remoteNodeId: PublicKey, to: ActorRef) +case class SendChannelQuery(remoteNodeId: PublicKey, to: ActorRef, flags_opt: Option[QueryChannelRangeExtension]) case object GetRoutingState case class RoutingState(channels: Iterable[ChannelAnnouncement], updates: Iterable[ChannelUpdate], nodes: Iterable[NodeAnnouncement]) case class Stash(updates: Map[ChannelUpdate, Set[ActorRef]], nodes: Map[NodeAnnouncement, Set[ActorRef]]) case class Rebroadcast(channels: Map[ChannelAnnouncement, Set[ActorRef]], updates: Map[ChannelUpdate, Set[ActorRef]], nodes: Map[NodeAnnouncement, Set[ActorRef]]) -case class Sync(missing: SortedSet[ShortChannelId], totalMissingCount: Int) +case class ShortChannelIdAndFlag(shortChannelId: ShortChannelId, flag: Long) + +case class Sync(pending: List[RoutingMessage], total: Int) case class Data(nodes: Map[PublicKey, NodeAnnouncement], channels: SortedMap[ShortChannelId, ChannelAnnouncement], @@ -107,7 +112,7 @@ case object TickPruneStaleChannels * Created by PM on 24/05/2016. */ -class Router(nodeParams: NodeParams, watcher: ActorRef, initialized: Option[Promise[Done]] = None) extends FSMDiagnosticActorLogging[State, Data] { +class Router(val nodeParams: NodeParams, watcher: ActorRef, initialized: Option[Promise[Done]] = None) extends FSMDiagnosticActorLogging[State, Data] { import Router._ @@ -422,11 +427,11 @@ class Router(nodeParams: NodeParams, watcher: ActorRef, initialized: Option[Prom .recover { case t => sender ! Status.Failure(t) } stay - case Event(SendChannelQuery(remoteNodeId, remote), d) => + case Event(SendChannelQuery(remoteNodeId, remote, flags_opt), d) => // ask for everything // we currently send only one query_channel_range message per peer, when we just (re)connected to it, so we don't // have to worry about sending a new query_channel_range when another query is still in progress - val query = QueryChannelRange(nodeParams.chainHash, firstBlockNum = 0, numberOfBlocks = Int.MaxValue) + val query = QueryChannelRange(nodeParams.chainHash, firstBlockNum = 0L, numberOfBlocks = Int.MaxValue.toLong, queryExtension = flags_opt) log.info("sending query_channel_range={}", query) remote ! query @@ -496,79 +501,111 @@ class Router(nodeParams: NodeParams, watcher: ActorRef, initialized: Option[Prom log.debug("received node announcement for nodeId={}", n.nodeId) stay using handle(n, sender, d) - case Event(PeerRoutingMessage(transport, _, routingMessage@QueryChannelRange(chainHash, firstBlockNum, numberOfBlocks)), d) => + case Event(PeerRoutingMessage(transport, _, routingMessage@QueryChannelRange(chainHash, firstBlockNum, numberOfBlocks, extendedQueryFlags_opt)), d) => sender ! TransportHandler.ReadAck(routingMessage) - log.info("received query_channel_range={}", routingMessage) - // sort channel ids and keep the ones which are in [firstBlockNum, firstBlockNum + numberOfBlocks] - val shortChannelIds: SortedSet[ShortChannelId] = d.channels.keySet.filter(keep(firstBlockNum, numberOfBlocks, _, d.channels, d.updates)) - // TODO: we don't compress to be compatible with old mobile apps, switch to ZLIB ASAP - // Careful: when we remove GZIP support, eclair-wallet 0.3.0 will stop working i.e. channels to ACINQ nodes will not - // work anymore - val blocks = ChannelRangeQueries.encodeShortChannelIds(firstBlockNum, numberOfBlocks, shortChannelIds, ChannelRangeQueries.UNCOMPRESSED_FORMAT) - log.info("sending back reply_channel_range with {} items for range=({}, {})", shortChannelIds.size, firstBlockNum, numberOfBlocks) - // there could be several reply_channel_range messages for a single query - val replies = blocks.map(block => ReplyChannelRange(chainHash, block.firstBlock, block.numBlocks, 1, block.shortChannelIds)) - replies.foreach(reply => transport ! reply) + log.info("received query_channel_range with firstBlockNum={} numberOfBlocks={} extendedQueryFlags_opt={}", firstBlockNum, numberOfBlocks, extendedQueryFlags_opt) + // keep channel ids that are in [firstBlockNum, firstBlockNum + numberOfBlocks] + val shortChannelIds: SortedSet[ShortChannelId] = d.channels.keySet.filter(keep(firstBlockNum, numberOfBlocks, _)) + log.info("replying with {} items for range=({}, {})", shortChannelIds.size, firstBlockNum, numberOfBlocks) + split(shortChannelIds) + .foreach(chunk => { + val (timestamps, checksums) = routingMessage.queryExtension match { + case Some(extension) if extension.wantChecksums | extension.wantTimestamps => + // we always compute timestamps and checksums even if we don't need both, overhead is negligible + val (timestamps, checksums) = chunk.shortChannelIds.map(getChannelDigestInfo(d.channels, d.updates)).unzip + val encodedTimestamps = if (extension.wantTimestamps) Some(EncodedTimestamps(EncodingType.UNCOMPRESSED, timestamps)) else None + val encodedChecksums = if (extension.wantChecksums) Some(EncodedChecksums(checksums)) else None + (encodedTimestamps, encodedChecksums) + case _ => (None, None) + } + val reply = ReplyChannelRange(chainHash, chunk.firstBlock, chunk.numBlocks, + complete = 1, + shortChannelIds = EncodedShortChannelIds(EncodingType.UNCOMPRESSED, chunk.shortChannelIds), + timestamps = timestamps, + checksums = checksums) + transport ! reply + }) stay - case Event(PeerRoutingMessage(transport, remoteNodeId, routingMessage@ReplyChannelRange(chainHash, firstBlockNum, numberOfBlocks, _, data)), d) => + case Event(PeerRoutingMessage(transport, remoteNodeId, routingMessage@ReplyChannelRange(chainHash, _, _, _, shortChannelIds, _)), d) => sender ! TransportHandler.ReadAck(routingMessage) - val (format, theirShortChannelIds, useGzip) = ChannelRangeQueries.decodeShortChannelIds(data) - val ourShortChannelIds: SortedSet[ShortChannelId] = d.channels.keySet.filter(keep(firstBlockNum, numberOfBlocks, _, d.channels, d.updates)) - val missing: SortedSet[ShortChannelId] = theirShortChannelIds -- ourShortChannelIds - log.info("received reply_channel_range, we're missing {} channel announcements/updates, format={} useGzip={}", missing.size, format, useGzip) - val d1 = if (missing.nonEmpty) { - // they may send back several reply_channel_range messages for a single query_channel_range query, and we must not - // send another query_short_channel_ids query if they're still processing one - d.sync.get(remoteNodeId) match { - case None => - // we don't have a pending query with this peer - val (slice, rest) = missing.splitAt(SHORTID_WINDOW) - transport ! QueryShortChannelIds(chainHash, ChannelRangeQueries.encodeShortChannelIdsSingle(slice, format, useGzip)) - d.copy(sync = d.sync + (remoteNodeId -> Sync(rest, missing.size))) - case Some(sync) => - // we already have a pending query with this peer, add missing ids to our "sync" state - d.copy(sync = d.sync + (remoteNodeId -> Sync(sync.missing ++ missing, sync.totalMissingCount + missing.size))) + val shortChannelIdAndFlags = shortChannelIds.array + .zipWithIndex + .map { + case (shortChannelId: ShortChannelId, idx) => { + val timestamps = routingMessage.timestamps.map(_.timestamps(idx)) + val checksums = routingMessage.checksums.map(_.checksums(idx)) + ShortChannelIdAndFlag(shortChannelId, computeFlag(d.channels, d.updates)(shortChannelId, timestamps, checksums)) + } } - } else d - context.system.eventStream.publish(syncProgress(d1)) - stay using d1 - - case Event(PeerRoutingMessage(transport, _, routingMessage@QueryShortChannelIds(chainHash, data)), d) => + .filter(_.flag != 0) + val (channelCount, updatesCount) = shortChannelIdAndFlags.foldLeft((0, 0)) { + case ((c, u), ShortChannelIdAndFlag(_, flag)) => + val c1 = c + (if (QueryFlagType.includeAnnouncement(flag)) 1 else 0) + val u1 = u + (if (QueryFlagType.includeUpdate1(flag)) 1 else 0) + (if (QueryFlagType.includeUpdate2(flag)) 1 else 0) + (c1, u1) + } + log.info(s"received reply_channel_range with {} channels, we're missing {} channel announcements and {} updates, format={}", shortChannelIds.array.size, channelCount, updatesCount, shortChannelIds.encoding) + // we update our sync data to this node (there may be multiple channel range responses and we can only query one set of ids at a time) + val replies = shortChannelIdAndFlags + .grouped(SHORTID_WINDOW) + .map(chunk => QueryShortChannelIds(chainHash, + shortChannelIds = EncodedShortChannelIds(shortChannelIds.encoding, chunk.map(_.shortChannelId)), + if (routingMessage.timestamps.isDefined || routingMessage.checksums.isDefined) Some(EncodedQueryFlags(shortChannelIds.encoding, chunk.map(_.flag))) else None + )) + .toList + val (sync1, replynow_opt) = updateSync(d.sync, remoteNodeId, replies) + // we only send a rely right away if there were no pending requests + replynow_opt.foreach(transport ! _) + context.system.eventStream.publish(syncProgress(sync1)) + stay using d.copy(sync = sync1) + + case Event(PeerRoutingMessage(transport, _, routingMessage@QueryShortChannelIds(chainHash, shortChannelIds, queryFlags_opt)), d) => sender ! TransportHandler.ReadAck(routingMessage) - val (_, shortChannelIds, useGzip) = ChannelRangeQueries.decodeShortChannelIds(data) - log.info("received query_short_channel_ids for {} channel announcements, useGzip={}", shortChannelIds.size, useGzip) - shortChannelIds.foreach(shortChannelId => { - d.channels.get(shortChannelId) match { - case None => log.warning("received query for shortChannelId={} that we don't have", shortChannelId) - case Some(ca) => - transport ! ca - d.updates.get(ChannelDesc(ca.shortChannelId, ca.nodeId1, ca.nodeId2)).map(u => transport ! u) - d.updates.get(ChannelDesc(ca.shortChannelId, ca.nodeId2, ca.nodeId1)).map(u => transport ! u) + val (channelCount, updatesCount) = shortChannelIds.array + .zipWithIndex + .foldLeft((0, 0)) { + case ((c, u), (shortChannelId, idx)) => + var c1 = c + var u1 = u + val flag = routingMessage.queryFlags.map(_.array(idx)).getOrElse(QueryFlagType.INCLUDE_ALL) + d.channels.get(shortChannelId) match { + case None => log.warning("received query for shortChannelId={} that we don't have", shortChannelId) + case Some(ca) => + if (QueryFlagType.includeAnnouncement(flag)) { + transport ! ca + c1 = c1 + 1 + } + if (QueryFlagType.includeUpdate1(flag)) d.updates.get(ChannelDesc(ca.shortChannelId, ca.nodeId1, ca.nodeId2)).foreach { u => transport ! u; u1 = u1 + 1 } + if (QueryFlagType.includeUpdate2(flag)) d.updates.get(ChannelDesc(ca.shortChannelId, ca.nodeId2, ca.nodeId1)).foreach { u => transport ! u; u1 = u1 + 1 } + } + (c1, u1) } - }) + log.info("received query_short_channel_ids with {} items, sent back {} channels and {} updates", shortChannelIds.array.size, channelCount, updatesCount) transport ! ReplyShortChannelIdsEnd(chainHash, 1) stay - case Event(PeerRoutingMessage(transport, remoteNodeId, routingMessage@ReplyShortChannelIdsEnd(chainHash, complete)), d) => + case Event(PeerRoutingMessage(transport, remoteNodeId, routingMessage: ReplyShortChannelIdsEnd), d) => sender ! TransportHandler.ReadAck(routingMessage) - log.info("received reply_short_channel_ids_end={}", routingMessage) // have we more channels to ask this peer? - val d1 = d.sync.get(remoteNodeId) match { - case Some(sync) if sync.missing.nonEmpty => - log.info(s"asking {} for the next slice of short_channel_ids", remoteNodeId) - val (slice, rest) = sync.missing.splitAt(SHORTID_WINDOW) - transport ! QueryShortChannelIds(chainHash, ChannelRangeQueries.encodeShortChannelIdsSingle(slice, ChannelRangeQueries.UNCOMPRESSED_FORMAT, useGzip = false)) - d.copy(sync = d.sync + (remoteNodeId -> sync.copy(missing = rest))) - case Some(sync) if sync.missing.isEmpty => - // we received reply_short_channel_ids_end for our last query aand have not sent another one, we can now remove - // the remote peer from our map - d.copy(sync = d.sync - remoteNodeId) - case _ => - d + val sync1 = d.sync.get(remoteNodeId) match { + case Some(sync) => + sync.pending match { + case nextRequest +: rest => + log.info(s"asking for the next slice of short_channel_ids (remaining=${sync.pending.size}/${sync.total})") + transport ! nextRequest + d.sync + (remoteNodeId -> sync.copy(pending = rest)) + case Nil => + // we received reply_short_channel_ids_end for our last query and have not sent another one, we can now remove + // the remote peer from our map + log.info(s"sync complete (total=${sync.total})") + d.sync - remoteNodeId + } + case _ => d.sync } - context.system.eventStream.publish(syncProgress(d1)) - stay using d1 + context.system.eventStream.publish(syncProgress(sync1)) + stay using d.copy(sync = sync1) + } initialize() @@ -698,18 +735,20 @@ class Router(nodeParams: NodeParams, watcher: ActorRef, initialized: Option[Prom // when we're sending updates to ourselves (transport_opt, remoteNodeId_opt) match { case (Some(transport), Some(remoteNodeId)) => + val query = QueryShortChannelIds(u.chainHash, EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(u.shortChannelId)), flags = None) d.sync.get(remoteNodeId) match { case Some(sync) => // we already have a pending request to that node, let's add this channel to the list and we'll get it later - d.copy(sync = d.sync + (remoteNodeId -> sync.copy(missing = sync.missing + u.shortChannelId, totalMissingCount = sync.totalMissingCount + 1))) + // TODO: we only request channels with old style channel_query + d.copy(sync = d.sync + (remoteNodeId -> sync.copy(pending = sync.pending :+ query, total = sync.total + 1))) case None => // we send the query right away - transport ! QueryShortChannelIds(u.chainHash, ChannelRangeQueries.encodeShortChannelIdsSingle(Seq(u.shortChannelId), ChannelRangeQueries.UNCOMPRESSED_FORMAT, useGzip = false)) - d.copy(sync = d.sync + (remoteNodeId -> Sync(missing = SortedSet(u.shortChannelId), totalMissingCount = 1))) + transport ! query + d.copy(sync = d.sync + (remoteNodeId -> Sync(pending = Nil, total = 1))) } case _ => // we don't know which node this update came from (maybe it was stashed and the channel got pruned in the meantime or some other corner case). - // or we don't have a transport to send our query with. + // or we don't have a transport to send our query to. // anyway, that's not really a big deal because we have removed the channel from the pruned db so next time it shows up we will revalidate it d } @@ -719,13 +758,14 @@ class Router(nodeParams: NodeParams, watcher: ActorRef, initialized: Option[Prom } override def mdc(currentMessage: Any): MDC = currentMessage match { - case SendChannelQuery(remoteNodeId, _) => Logs.mdc(remoteNodeId_opt = Some(remoteNodeId)) + case SendChannelQuery(remoteNodeId, _, _) => Logs.mdc(remoteNodeId_opt = Some(remoteNodeId)) case PeerRoutingMessage(_, remoteNodeId, _) => Logs.mdc(remoteNodeId_opt = Some(remoteNodeId)) case _ => akka.event.Logging.emptyMDC } } object Router { + val SHORTID_WINDOW = 100 def props(nodeParams: NodeParams, watcher: ActorRef, initialized: Option[Promise[Done]] = None) = Props(new Router(nodeParams, watcher, initialized)) @@ -751,11 +791,19 @@ object Router { def hasChannels(nodeId: PublicKey, channels: Iterable[ChannelAnnouncement]): Boolean = channels.exists(c => isRelatedTo(c, nodeId)) - def isStale(u: ChannelUpdate): Boolean = { + def isStale(u: ChannelUpdate): Boolean = isStale(u.timestamp) + + def isStale(timestamp: Long): Boolean = { // BOLT 7: "nodes MAY prune channels should the timestamp of the latest channel_update be older than 2 weeks" // but we don't want to prune brand new channels for which we didn't yet receive a channel update val staleThresholdSeconds = (Platform.currentTime.milliseconds - 14.days).toSeconds - u.timestamp < staleThresholdSeconds + timestamp < staleThresholdSeconds + } + + def isAlmostStale(timestamp: Long): Boolean = { + // we define almost stale as 2 weeks minus 4 days + val staleThresholdSeconds = (Platform.currentTime.milliseconds - 10.days).toSeconds + timestamp < staleThresholdSeconds } /** @@ -789,17 +837,64 @@ object Router { /** * Filters channels that we want to send to nodes asking for a channel range */ - def keep(firstBlockNum: Long, numberOfBlocks: Long, id: ShortChannelId, channels: Map[ShortChannelId, ChannelAnnouncement], updates: Map[ChannelDesc, ChannelUpdate]): Boolean = { + def keep(firstBlockNum: Long, numberOfBlocks: Long, id: ShortChannelId): Boolean = { val TxCoordinates(height, _, _) = ShortChannelId.coordinates(id) height >= firstBlockNum && height <= (firstBlockNum + numberOfBlocks) } - def syncProgress(d: Data): SyncProgress = - if (d.sync.isEmpty) { + def computeFlag(channels: SortedMap[ShortChannelId, ChannelAnnouncement], updates: Map[ChannelDesc, ChannelUpdate])( + shortChannelId: ShortChannelId, + timestamps_opt: Option[Timestamps], + checksums_opt: Option[Checksums]): Long = { + var flag = 0L + (timestamps_opt, checksums_opt) match { + case (Some(theirTimestamps), Some(theirChecksums)) if channels.contains(shortChannelId) => + val (ourTimestamps, ourChecksums) = Router.getChannelDigestInfo(channels, updates)(shortChannelId) + // we request their channel_update if all those conditions are met: + // - it is more recent than ours + // - it is different from ours, or it is the same but ours is about to be stale + // - it is not stale itself + if (ourTimestamps.timestamp1 < theirTimestamps.timestamp1 && (ourChecksums.checksum1 != theirChecksums.checksum1 || isAlmostStale(ourTimestamps.timestamp1)) && !isStale(theirTimestamps.timestamp1)) flag = flag | QueryFlagType.INCLUDE_CHANNEL_UPDATE_1 + if (ourTimestamps.timestamp2 < theirTimestamps.timestamp2 && (ourChecksums.checksum2 != theirChecksums.checksum2 || isAlmostStale(ourTimestamps.timestamp1)) && !isStale(theirTimestamps.timestamp2)) flag = flag | QueryFlagType.INCLUDE_CHANNEL_UPDATE_2 + case (Some(theirTimestamps), None) if channels.contains(shortChannelId) => + val (ourTimestamps, _) = Router.getChannelDigestInfo(channels, updates)(shortChannelId) + // we request their channel_update if all those conditions are met: + // - it is more recent than ours + // - it is not stale itself + if (ourTimestamps.timestamp1 < theirTimestamps.timestamp1 && !isStale(theirTimestamps.timestamp1)) flag = flag | QueryFlagType.INCLUDE_CHANNEL_UPDATE_1 + if (ourTimestamps.timestamp2 < theirTimestamps.timestamp2 && !isStale(theirTimestamps.timestamp2)) flag = flag | QueryFlagType.INCLUDE_CHANNEL_UPDATE_2 + case (None, Some(theirChecksums)) if channels.contains(shortChannelId) => + val (_, ourChecksums) = Router.getChannelDigestInfo(channels, updates)(shortChannelId) + // this should not happen as we will not ask for checksums without asking for timestamps too + if (ourChecksums.checksum1 != theirChecksums.checksum1 && theirChecksums.checksum1 != 0) flag = flag | QueryFlagType.INCLUDE_CHANNEL_UPDATE_1 + if (ourChecksums.checksum2 != theirChecksums.checksum2 && theirChecksums.checksum2 != 0) flag = flag | QueryFlagType.INCLUDE_CHANNEL_UPDATE_2 + case (None, None) if channels.contains(shortChannelId) => + // we know this channel: we only request their channel updates + flag = QueryFlagType.INCLUDE_CHANNEL_UPDATE_1 | QueryFlagType.INCLUDE_CHANNEL_UPDATE_2 + case _ => + // we don't know this channel: we request everything + flag = QueryFlagType.INCLUDE_CHANNEL_ANNOUNCEMENT | QueryFlagType.INCLUDE_CHANNEL_UPDATE_1 | QueryFlagType.INCLUDE_CHANNEL_UPDATE_2 + } + flag + } + + /** + * Returns overall progress on synchronization + * + * @param sync + * @return a sync progress indicator (1 means fully synced) + */ + def syncProgress(sync: Map[PublicKey, Sync]): SyncProgress = { + //NB: progress is in terms of requests, not individual channels + val (pending, total) = sync.foldLeft((0, 0)) { + case ((p, t), (_, sync)) => (p + sync.pending.size, t + sync.total) + } + if (total == 0) { SyncProgress(1) } else { - SyncProgress(1 - d.sync.values.map(_.missing.size).sum * 1.0 / d.sync.values.map(_.totalMissingCount).sum) + SyncProgress((total - pending) / (1.0 * total)) } + } /** * This method is used after a payment failed, and we want to exclude some nodes that we know are failing @@ -814,6 +909,90 @@ object Router { desc } + /** + * + * @param channels id -> announcement map + * @param updates channel updates + * @param id short channel id + * @return the timestamp of the most recent update for this channel id, 0 if we don't have any + */ + def getTimestamp(channels: SortedMap[ShortChannelId, ChannelAnnouncement], updates: Map[ChannelDesc, ChannelUpdate])(id: ShortChannelId): Long = { + val ca = channels(id) + val opt1 = updates.get(ChannelDesc(ca.shortChannelId, ca.nodeId1, ca.nodeId2)) + val opt2 = updates.get(ChannelDesc(ca.shortChannelId, ca.nodeId2, ca.nodeId1)) + val timestamp = (opt1, opt2) match { + case (Some(u1), Some(u2)) => Math.max(u1.timestamp, u2.timestamp) + case (Some(u1), None) => u1.timestamp + case (None, Some(u2)) => u2.timestamp + case (None, None) => 0L + } + timestamp + } + + def getChannelDigestInfo(channels: SortedMap[ShortChannelId, ChannelAnnouncement], updates: Map[ChannelDesc, ChannelUpdate])(shortChannelId: ShortChannelId): (Timestamps, Checksums) = { + val c = channels(shortChannelId) + val u1_opt = updates.get(ChannelDesc(c.shortChannelId, c.nodeId1, c.nodeId2)) + val u2_opt = updates.get(ChannelDesc(c.shortChannelId, c.nodeId2, c.nodeId1)) + val timestamp1 = u1_opt.map(_.timestamp).getOrElse(0L) + val timestamp2 = u2_opt.map(_.timestamp).getOrElse(0L) + val checksum1 = u1_opt.map(getChecksum).getOrElse(0L) + val checksum2 = u2_opt.map(getChecksum).getOrElse(0L) + (Timestamps(timestamp1 = timestamp1, timestamp2 = timestamp2), Checksums(checksum1 = checksum1, checksum2 = checksum2)) + } + + def getChecksum(u: ChannelUpdate): Long = { + import u._ + val data = serializationResult(LightningMessageCodecs.channelUpdateChecksumCodec.encode(shortChannelId :: messageFlags :: channelFlags :: cltvExpiryDelta :: htlcMinimumMsat :: feeBaseMsat :: feeProportionalMillionths :: htlcMaximumMsat :: HNil)) + val checksum = new CRC32() + checksum.update(data.toArray) + checksum.getValue + } + + case class ShortChannelIdsChunk(firstBlock: Long, numBlocks: Long, shortChannelIds: List[ShortChannelId]) + + /** + * Have to split ids because otherwise message could be too big + * there could be several reply_channel_range messages for a single query + * + * @param shortChannelIds + * @return + */ + def split(shortChannelIds: SortedSet[ShortChannelId]): List[ShortChannelIdsChunk] = { + // TODO: this is wrong because it can split blocks + if (shortChannelIds.isEmpty) { + List(ShortChannelIdsChunk(0, 0, List.empty)) + } else { + shortChannelIds + .grouped(2000) // LN messages must fit in 65 Kb so we split ids into groups to make sure that the output message will be valid + .toList + .map { group => + // NB: group is never empty + val firstBlock: Long = ShortChannelId.coordinates(group.head).blockHeight.toLong + val numBlocks: Long = ShortChannelId.coordinates(group.last).blockHeight.toLong - firstBlock + 1 + ShortChannelIdsChunk(firstBlock, numBlocks, group.toList) + } + } + } + + def updateSync(syncMap: Map[PublicKey, Sync], remoteNodeId: PublicKey, pending: List[RoutingMessage]): (Map[PublicKey, Sync], Option[RoutingMessage]) = { + pending match { + case head +: rest => + // they may send back several reply_channel_range messages for a single query_channel_range query, and we must not + // send another query_short_channel_ids query if they're still processing one + syncMap.get(remoteNodeId) match { + case None => + // we don't have a pending query with this peer, let's send it + (syncMap + (remoteNodeId -> Sync(rest, pending.size)), Some(head)) + case Some(sync) => + // we already have a pending query with this peer, add missing ids to our "sync" state + (syncMap + (remoteNodeId -> Sync(sync.pending ++ pending, sync.total + pending.size)), None) + } + case Nil => + // there is nothing to send + (syncMap, None) + } + } + /** * https://github.com/lightningnetwork/lightning-rfc/blob/master/04-onion-routing.md#clarifications */ 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/CommonCodecs.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/CommonCodecs.scala index 143a516667..6f8100ce3a 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/CommonCodecs.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/CommonCodecs.scala @@ -18,14 +18,15 @@ package fr.acinq.eclair.wire import java.net.{Inet4Address, Inet6Address, InetAddress} -import fr.acinq.bitcoin.{ByteVector32, ByteVector64} import fr.acinq.bitcoin.Crypto.{PrivateKey, PublicKey} +import fr.acinq.bitcoin.{ByteVector32, ByteVector64} import fr.acinq.eclair.{ShortChannelId, UInt64} import org.apache.commons.codec.binary.Base32 -import scodec.{Attempt, Codec, DecodeResult, Err, SizeBound} import scodec.bits.{BitVector, ByteVector} import scodec.codecs._ +import scodec.{Attempt, Codec, DecodeResult, Err, SizeBound} +import scala.Ordering.Implicits._ import scala.util.Try /** @@ -56,14 +57,15 @@ object CommonCodecs { val uint64L: Codec[UInt64] = bytes(8).xmap(b => UInt64(b.reverse), a => a.toByteVector.padLeft(8).reverse) /** - * We impose a minimal encoding on varint values to ensure that signed hashes can be reproduced easily. + * We impose a minimal encoding on some values (such as varint and truncated int) to ensure that signed hashes can be + * re-computed correctly. * If a value could be encoded with less bytes, it's considered invalid and results in a failed decoding attempt. * - * @param codec the integer codec (depends on the value). + * @param codec the value codec (depends on the value). * @param min the minimal value that should be encoded. */ - def uint64min(codec: Codec[UInt64], min: UInt64): Codec[UInt64] = codec.exmap({ - case i if i < min => Attempt.failure(Err("varint was not minimally encoded")) + def minimalvalue[A : Ordering](codec: Codec[A], min: A): Codec[A] = codec.exmap({ + case i if i < min => Attempt.failure(Err("value was not minimally encoded")) case i => Attempt.successful(i) }, Attempt.successful) @@ -71,9 +73,9 @@ object CommonCodecs { // See https://bitcoin.org/en/developer-reference#compactsize-unsigned-integers for reference. val varint: Codec[UInt64] = discriminatorWithDefault( discriminated[UInt64].by(uint8L) - .\(0xff) { case i if i >= UInt64(0x100000000L) => i }(uint64min(uint64L, UInt64(0x100000000L))) - .\(0xfe) { case i if i >= UInt64(0x10000) => i }(uint64min(uint32L.xmap(UInt64(_), _.toBigInt.toLong), UInt64(0x10000))) - .\(0xfd) { case i if i >= UInt64(0xfd) => i }(uint64min(uint16L.xmap(UInt64(_), _.toBigInt.toInt), UInt64(0xfd))), + .\(0xff) { case i if i >= UInt64(0x100000000L) => i }(minimalvalue(uint64L, UInt64(0x100000000L))) + .\(0xfe) { case i if i >= UInt64(0x10000) => i }(minimalvalue(uint32L.xmap(UInt64(_), _.toBigInt.toLong), UInt64(0x10000))) + .\(0xfd) { case i if i >= UInt64(0xfd) => i }(minimalvalue(uint16L.xmap(UInt64(_), _.toBigInt.toInt), UInt64(0xfd))), uint8L.xmap(UInt64(_), _.toBigInt.toInt) ) 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..06559286a5 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,18 @@ 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.{UInt64, 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 +161,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 +178,30 @@ 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 channelUpdateChecksumCodec = + ("shortChannelId" | shortchannelid) :: + (("messageFlags" | byte) >>:~ { messageFlags => + ("channelFlags" | byte) :: + ("cltvExpiryDelta" | uint16) :: + ("htlcMinimumMsat" | uint64overflow) :: + ("feeBaseMsat" | uint32) :: + ("feeProportionalMillionths" | uint32) :: + ("htlcMaximumMsat" | conditional((messageFlags & 1) != 0, uint64overflow)) + }) + val channelUpdateWitnessCodec = ("chainHash" | bytes32) :: ("shortChannelId" | shortchannelid) :: @@ -190,36 +212,94 @@ 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] = ( ("signature" | bytes64) :: channelUpdateWitnessCodec).as[ChannelUpdate] - val queryShortChannelIdsCodec: Codec[QueryShortChannelIds] = ( - ("chainHash" | bytes32) :: - ("data" | varsizebinarydata) + val encodedShortChannelIdsCodec: Codec[EncodedShortChannelIds] = + discriminated[EncodedShortChannelIds].by(byte) + .\(0) { case a@EncodedShortChannelIds(EncodingType.UNCOMPRESSED, _) => a }((provide[EncodingType](EncodingType.UNCOMPRESSED) :: list(shortchannelid)).as[EncodedShortChannelIds]) + .\(1) { case a@EncodedShortChannelIds(EncodingType.COMPRESSED_ZLIB, _) => a }((provide[EncodingType](EncodingType.COMPRESSED_ZLIB) :: zlib(list(shortchannelid))).as[EncodedShortChannelIds]) + + val encodedQueryFlagsCodec: Codec[EncodedQueryFlags] = + discriminated[EncodedQueryFlags].by(byte) + .\(0) { case a@EncodedQueryFlags(EncodingType.UNCOMPRESSED, _) => a }((provide[EncodingType](EncodingType.UNCOMPRESSED) :: list(varintoverflow)).as[EncodedQueryFlags]) + .\(1) { case a@EncodedQueryFlags(EncodingType.COMPRESSED_ZLIB, _) => a }((provide[EncodingType](EncodingType.COMPRESSED_ZLIB) :: zlib(list(varintoverflow))).as[EncodedQueryFlags]) + + val queryShortChannelIdsCodec: Codec[QueryShortChannelIds] = { + val extensionsCodec = TlvCodecs.tlvStream(discriminated[Tlv].by(varint) + .typecase(EncodedQueryFlags.`type`, variableSizeBytesLong(varintoverflow, encodedQueryFlagsCodec)) + ) + + Codec( + ("chainHash" | bytes32) :: + ("shortChannelIds" | variableSizeBytes(uint16, encodedShortChannelIdsCodec)) :: + ("extensions" | extensionsCodec) ).as[QueryShortChannelIds] + } val replyShortChanelIdsEndCodec: Codec[ReplyShortChannelIdsEnd] = ( ("chainHash" | bytes32) :: ("complete" | byte) ).as[ReplyShortChannelIdsEnd] - val queryChannelRangeCodec: Codec[QueryChannelRange] = ( - ("chainHash" | bytes32) :: - ("firstBlockNum" | uint32) :: - ("numberOfBlocks" | uint32) - ).as[QueryChannelRange] - - val replyChannelRangeCodec: Codec[ReplyChannelRange] = ( - ("chainHash" | bytes32) :: - ("firstBlockNum" | uint32) :: - ("numberOfBlocks" | uint32) :: - ("complete" | byte) :: - ("data" | varsizebinarydata) - ).as[ReplyChannelRange] + val queryChannelRangeExtensionCodec: Codec[QueryChannelRangeExtension] = Codec(("flag" | varintoverflow)).as[QueryChannelRangeExtension] + + val queryChannelRangeExtensionType = UInt64(1) + + val queryChannelRangeCodec: Codec[QueryChannelRange] = { + val extensionsCodec = TlvCodecs.tlvStream(discriminated[Tlv].by(varint) + .typecase(queryChannelRangeExtensionType, variableSizeBytesLong(varintoverflow, queryChannelRangeExtensionCodec)) + ) + + Codec( + ("chainHash" | bytes32) :: + ("firstBlockNum" | uint32) :: + ("numberOfBlocks" | uint32) :: + ("extensions" | extensionsCodec) + ).as[QueryChannelRange] + } + + val timestampsCodec: Codec[Timestamps] = ( + ("checksum1" | uint32) :: + ("checksum2" | uint32) + ).as[Timestamps] + + val encodedTimestampsCodec: Codec[EncodedTimestamps] = + discriminated[EncodedTimestamps].by(byte) + .\(0) { case a@EncodedTimestamps(EncodingType.UNCOMPRESSED, _) => a }((provide[EncodingType](EncodingType.UNCOMPRESSED) :: list(timestampsCodec)).as[EncodedTimestamps]) + .\(1) { case a@EncodedTimestamps(EncodingType.COMPRESSED_ZLIB, _) => a }((provide[EncodingType](EncodingType.COMPRESSED_ZLIB) :: zlib(list(timestampsCodec))).as[EncodedTimestamps]) + + val encodedTimestampsType = UInt64(1) + + val checksumsCodec: Codec[Checksums] = ( + ("checksum1" | uint32) :: + ("checksum2" | uint32) + ).as[Checksums] + + val encodedChecksumsCodec: Codec[EncodedChecksums] = Codec(("checksums" | list(checksumsCodec))).as[EncodedChecksums] + + val encodedChecksumsType = UInt64(3) + + val replyChannelRangeCodec: Codec[ReplyChannelRange] = { + val extensionsCodec = TlvCodecs.tlvStream(discriminated[Tlv].by(varint) + .typecase(encodedTimestampsType, variableSizeBytesLong(varintoverflow, encodedTimestampsCodec)) + .typecase(encodedChecksumsType, variableSizeBytesLong(varintoverflow, encodedChecksumsCodec)) + ) + + Codec( + ("chainHash" | bytes32) :: + ("firstBlockNum" | uint32) :: + ("numberOfBlocks" | uint32) :: + ("complete" | byte) :: + ("shortChannelIds" | variableSizeBytes(uint16, encodedShortChannelIdsCodec)) :: + ("extensions" | extensionsCodec) + ).as[ReplyChannelRange] + } val gossipTimestampFilterCodec: Codec[GossipTimestampFilter] = ( ("chainHash" | bytes32) :: 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..984968d5f4 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") } @@ -226,22 +229,150 @@ case class PerHopPayload(shortChannelId: ShortChannelId, amtToForward: Long, outgoingCltvValue: Long) + +/** + * Optional TLV-based query message that can be appended to QueryShortChannelIds + * @param encoding 0 means uncompressed, 1 means compressed with zlib + * @param array array of query flags, each flags specifies the info we want for a given channel + */ +case class EncodedQueryFlags(encoding: EncodingType, array: List[Long]) extends Tlv + +object EncodedQueryFlags { + val `type` = UInt64(1) +} + +case object QueryFlagType { + val INCLUDE_CHANNEL_ANNOUNCEMENT: Long = 1 + val INCLUDE_CHANNEL_UPDATE_1: Long = 2 + val INCLUDE_CHANNEL_UPDATE_2: Long = 4 + val INCLUDE_ALL: Long = (INCLUDE_CHANNEL_ANNOUNCEMENT | INCLUDE_CHANNEL_UPDATE_1 | INCLUDE_CHANNEL_UPDATE_2) + + def includeAnnouncement(flag: Long) = (flag & INCLUDE_CHANNEL_ANNOUNCEMENT) != 0 + + def includeUpdate1(flag: Long) = (flag & INCLUDE_CHANNEL_UPDATE_1) != 0 + + def includeUpdate2(flag: Long) = (flag & INCLUDE_CHANNEL_UPDATE_2) != 0 +} + +/** + * Optional query flag that is appended to QueryChannelRange + * @param flag bit 1 set means I want timestamps, bit 2 set means I want checksums + */ +case class QueryChannelRangeExtension(flag: Long) extends Tlv { + val wantTimestamps = QueryChannelRangeExtension.wantTimestamps(flag) + + val wantChecksums = QueryChannelRangeExtension.wantChecksums(flag) +} + +case object QueryChannelRangeExtension { + val WANT_TIMESTAMPS: Long = 1 + val WANT_CHECKSUMS: Long = 2 + val WANT_ALL: Long = (WANT_TIMESTAMPS | WANT_CHECKSUMS) + + def wantTimestamps(flag: Long) = (flag & WANT_TIMESTAMPS) != 0 + + def wantChecksums(flag: Long) = (flag & WANT_CHECKSUMS) != 0 +} + + +/** + * + * @param timestamp1 timestamp for node 1, or 0 + * @param timestamp2 timestamp for node 2, or 0 + */ +case class Timestamps(timestamp1: Long, timestamp2: Long) + +/** + * Optional timestamps TLV that can be appended to ReplyChannelRange + * @param encoding same convention as for short channel ids + * @param timestamps + */ +case class EncodedTimestamps(encoding: EncodingType, timestamps: List[Timestamps]) extends Tlv + +/** + * + * @param checksum1 checksum for node 1, or 0 + * @param checksum2 checksum for node 2, or 0 + */ +case class Checksums(checksum1: Long, checksum2: Long) + +/** + * Optional checksums TLV that can be appended to ReplyChannelRange + * There is no leading encoding byte, as compression would ne be very effective + * @param checksums + */ +case class EncodedChecksums(checksums: List[Checksums]) extends Tlv + +// @formatter:on +sealed trait EncodingType +object EncodingType { + case object UNCOMPRESSED extends EncodingType + case object COMPRESSED_ZLIB extends EncodingType +} +// @formatter:on + + +case class EncodedShortChannelIds(encoding: EncodingType, + array: List[ShortChannelId]) + + case class QueryShortChannelIds(chainHash: ByteVector32, - data: ByteVector) extends RoutingMessage with HasChainHash + shortChannelIds: EncodedShortChannelIds, + extensions: TlvStream[Tlv]) extends RoutingMessage with HasChainHash { + val queryFlags: Option[EncodedQueryFlags] = extensions.records collectFirst { case flags: EncodedQueryFlags => flags } +} + +object QueryShortChannelIds { + def apply(chainHash: ByteVector32, shortChannelIds: EncodedShortChannelIds, flags: Option[EncodedQueryFlags]) = new QueryShortChannelIds(chainHash, shortChannelIds, TlvStream(flags.toList)) +} + +case class QueryShortChannelIdsOld(chainHash: ByteVector32, + shortChannelIds: EncodedShortChannelIds, + queryFlags_opt: Option[EncodedQueryFlags]) extends RoutingMessage with HasChainHash + +case class ReplyShortChannelIdsEnd(chainHash: ByteVector32, + complete: Byte) extends RoutingMessage with HasChainHash + case class QueryChannelRange(chainHash: ByteVector32, firstBlockNum: Long, - numberOfBlocks: Long) extends RoutingMessage with HasChainHash + numberOfBlocks: Long, + extensions: TlvStream[Tlv]) extends RoutingMessage { + val queryExtension: Option[QueryChannelRangeExtension] = extensions.records collectFirst { case q: QueryChannelRangeExtension => q } +} + +object QueryChannelRange { + def apply(chainHash: ByteVector32, firstBlockNum: Long, numberOfBlocks: Long, queryExtension: Option[QueryChannelRangeExtension]) = { + new QueryChannelRange(chainHash, firstBlockNum, numberOfBlocks, TlvStream(queryExtension.toList)) + } +} case class ReplyChannelRange(chainHash: ByteVector32, firstBlockNum: Long, numberOfBlocks: Long, complete: Byte, - data: ByteVector) extends RoutingMessage with HasChainHash + shortChannelIds: EncodedShortChannelIds, + extensions: TlvStream[Tlv]) extends RoutingMessage { + val timestamps: Option[EncodedTimestamps] = extensions.records collectFirst { case ts: EncodedTimestamps => ts } + + val checksums: Option[EncodedChecksums] = extensions.records collectFirst { case cs: EncodedChecksums => cs } +} + +object ReplyChannelRange { + def apply(chainHash: ByteVector32, + firstBlockNum: Long, + numberOfBlocks: Long, + complete: Byte, + shortChannelIds: EncodedShortChannelIds, + timestamps: Option[EncodedTimestamps], + checksums: Option[EncodedChecksums]) = { + timestamps.foreach(ts => require(ts.timestamps.length == shortChannelIds.array.length)) + checksums.foreach(cs => require(cs.checksums.length == shortChannelIds.array.length)) + new ReplyChannelRange(chainHash, firstBlockNum, numberOfBlocks, complete, shortChannelIds, TlvStream(timestamps.toList ::: checksums.toList)) + } +} -case class ReplyShortChannelIdsEnd(chainHash: ByteVector32, - complete: Byte) extends RoutingMessage with HasChainHash case class GossipTimestampFilter(chainHash: ByteVector32, firstTimestamp: Long, - timestampRange: Long) extends RoutingMessage with HasChainHash \ No newline at end of file + timestampRange: Long) extends RoutingMessage with HasChainHash 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..664f7182ca 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 @@ -16,11 +16,11 @@ package fr.acinq.eclair.wire +import fr.acinq.eclair.UInt64 +import fr.acinq.eclair.UInt64.Conversions._ import fr.acinq.eclair.wire.CommonCodecs._ -import scodec.{Attempt, Codec} import scodec.codecs._ - -import scala.util.Try +import scodec.{Attempt, Codec, Err} /** * Created by t-bast on 20/06/2019. @@ -28,25 +28,94 @@ import scala.util.Try object TlvCodecs { - val genericTlv: Codec[GenericTlv] = (("type" | varint) :: variableSizeBytesLong(varintoverflow, bytes)).as[GenericTlv] + private def variableSizeUInt64(size: Int, min: UInt64): Codec[UInt64] = minimalvalue(bytes(size).xmap(UInt64(_), _.toByteVector.takeRight(size)), min) - def tlvFallback(codec: Codec[Tlv]): Codec[Tlv] = discriminatorFallback(genericTlv, codec).xmap({ - case Left(l) => l - case Right(r) => r - }, { - case g: GenericTlv => Left(g) - case o => Right(o) - }) + /** + * Length-prefixed truncated uint64 (1 to 9 bytes unsigned integer). + */ + val tu64: Codec[UInt64] = discriminated[UInt64].by(uint8) + .\(0x00) { case i if i < 0x01 => i }(variableSizeUInt64(0, 0x00)) + .\(0x01) { case i if i < 0x0100 => i }(variableSizeUInt64(1, 0x01)) + .\(0x02) { case i if i < 0x010000 => i }(variableSizeUInt64(2, 0x0100)) + .\(0x03) { case i if i < 0x01000000 => i }(variableSizeUInt64(3, 0x010000)) + .\(0x04) { case i if i < 0x0100000000L => i }(variableSizeUInt64(4, 0x01000000)) + .\(0x05) { case i if i < 0x010000000000L => i }(variableSizeUInt64(5, 0x0100000000L)) + .\(0x06) { case i if i < 0x01000000000000L => i }(variableSizeUInt64(6, 0x010000000000L)) + .\(0x07) { case i if i < 0x0100000000000000L => i }(variableSizeUInt64(7, 0x01000000000000L)) + .\(0x08) { case i if i <= UInt64.MaxValue => i }(variableSizeUInt64(8, 0x0100000000000000L)) + + /** + * Length-prefixed truncated uint32 (1 to 5 bytes unsigned integer). + */ + val tu32: Codec[Long] = tu64.exmap({ + case i if i > 0xffffffffL => Attempt.Failure(Err("tu32 overflow")) + case i => Attempt.Successful(i.toBigInt.toLong) + }, l => Attempt.Successful(l)) + + /** + * Length-prefixed truncated uint16 (1 to 3 bytes unsigned integer). + */ + val tu16: Codec[Int] = tu32.exmap({ + case i if i > 0xffff => Attempt.Failure(Err("tu16 overflow")) + case i => Attempt.Successful(i.toInt) + }, l => Attempt.Successful(l)) + + private def validateGenericTlv(g: GenericTlv): Attempt[GenericTlv] = { + if (g.tag.toBigInt % 2 == 0) { + Attempt.Failure(Err("unknown even tlv type")) + } else { + Attempt.Successful(g) + } + } + + private val genericTlv: Codec[GenericTlv] = (("tag" | varint) :: variableSizeBytesLong(varintoverflow, bytes)).as[GenericTlv].exmap(validateGenericTlv, validateGenericTlv) + + private def tag[T <: Tlv](codec: DiscriminatorCodec[T, UInt64], record: Either[GenericTlv, T]): UInt64 = record match { + case Left(generic) => generic.tag + case Right(tlv) => tag(codec, tlv) + } + + private def tag[T <: Tlv](codec: DiscriminatorCodec[T, UInt64], record: T): UInt64 = + codec.encode(record).flatMap(bits => varint.decode(bits)).require.value + + private def validateStream[T <: Tlv](codec: DiscriminatorCodec[T, UInt64], records: List[Either[GenericTlv, T]]): Attempt[TlvStream[T]] = { + val tags = records.map(r => tag(codec, r)) + if (tags.length != tags.distinct.length) { + Attempt.Failure(Err("tlv streams must not contain duplicate records")) + } else if (tags != tags.sorted) { + Attempt.Failure(Err("tlv records must be ordered by monotonically-increasing types")) + } else { + Attempt.Successful(TlvStream(records.collect { case Right(tlv) => tlv }, records.collect { case Left(generic) => generic })) + } + } /** * A tlv stream codec relies on an underlying tlv codec. * This allows tlv streams to have different namespaces, increasing the total number of tlv types available. * * @param codec codec used for the tlv records contained in the stream. + * @tparam T stream namespace. */ - def tlvStream(codec: Codec[Tlv]): Codec[TlvStream] = list(codec).exmap( - records => Attempt.fromTry(Try(TlvStream(records))), - stream => Attempt.successful(stream.records.toList) + def tlvStream[T <: Tlv](codec: DiscriminatorCodec[T, UInt64]): Codec[TlvStream[T]] = list(discriminatorFallback(genericTlv, codec)).exmap( + records => validateStream(codec, records), + (stream: TlvStream[T]) => { + val records = (stream.records.map(Right(_)) ++ stream.unknown.map(Left(_))).toList + val tags = records.map(r => tag(codec, r)) + if (tags.length != tags.distinct.length) { + Attempt.Failure(Err("tlv streams must not contain duplicate records")) + } else { + Attempt.Successful(tags.zip(records).sortBy(_._1).map(_._2)) + } + } ) + /** + * When used inside a message, most of the time a tlv stream needs to specify its length. + * Note that some messages will have an independent length field and won't need this codec. + * + * @param codec codec used for the tlv records contained in the stream. + * @tparam T stream namespace. + */ + def lengthPrefixedTlvStream[T <: Tlv](codec: DiscriminatorCodec[T, UInt64]): Codec[TlvStream[T]] = variableSizeBytesLong(CommonCodecs.varintoverflow, tlvStream(codec)) + } diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/TlvTypes.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/TlvTypes.scala index 84d38a090f..e4eea124f8 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/TlvTypes.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/TlvTypes.scala @@ -19,45 +19,36 @@ package fr.acinq.eclair.wire import fr.acinq.eclair.UInt64 import scodec.bits.ByteVector -import scala.annotation.tailrec - /** * Created by t-bast on 20/06/2019. */ // @formatter:off -trait Tlv { - val `type`: UInt64 -} +trait Tlv sealed trait OnionTlv extends Tlv // @formatter:on /** - * Generic tlv type we fallback to if we don't understand the incoming type. + * Generic tlv type we fallback to if we don't understand the incoming tlv. * - * @param `type` tlv type. - * @param value tlv value (length is implicit, and encoded as a varint). + * @param tag tlv tag. + * @param value tlv value (length is implicit, and encoded as a varint). */ -case class GenericTlv(`type`: UInt64, value: ByteVector) extends Tlv +case class GenericTlv(tag: UInt64, value: ByteVector) extends Tlv /** * A tlv stream is a collection of tlv records. - * A tlv stream is part of a given namespace that dictates how to parse the tlv records. - * That namespace is indicated by a trait extending the top-level tlv trait. + * A tlv stream is constrained to a specific tlv namespace that dictates how to parse the tlv records. + * That namespace is provided by a trait extending the top-level tlv trait. * - * @param records tlv records. + * @param records known tlv records. + * @param unknown unknown tlv records. + * @tparam T the stream namespace is a trait extending the top-level tlv trait. */ -case class TlvStream(records: Seq[Tlv]) { - - records.foldLeft(Option.empty[Tlv]) { - case (None, record) => - require(!record.isInstanceOf[GenericTlv] || record.`type`.toBigInt % 2 != 0, "tlv streams must not contain unknown even tlv types") - Some(record) - case (Some(previousRecord), record) => - require(record.`type` != previousRecord.`type`, "tlv streams must not contain duplicate records") - require(record.`type` > previousRecord.`type`, "tlv records must be ordered by monotonically-increasing types") - require(!record.isInstanceOf[GenericTlv] || record.`type`.toBigInt % 2 != 0, "tlv streams must not contain unknown even tlv types") - Some(record) - } +case class TlvStream[T <: Tlv](records: Traversable[T], unknown: Traversable[GenericTlv] = Nil) + +object TlvStream { + + def apply[T <: Tlv](records: T*): TlvStream[T] = TlvStream(records, Nil) } \ No newline at end of file diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/FeaturesSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/FeaturesSpec.scala index a0813d961b..25420f70ad 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/FeaturesSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/FeaturesSpec.scala @@ -16,10 +16,6 @@ package fr.acinq.eclair -import java.nio.ByteOrder - -import fr.acinq.bitcoin.Protocol -import fr.acinq.eclair.Features._ import org.scalatest.FunSuite import scodec.bits._ @@ -30,25 +26,27 @@ import scodec.bits._ class FeaturesSpec extends FunSuite { test("'initial_routing_sync' feature") { - assert(hasFeature(hex"08", Features.INITIAL_ROUTING_SYNC_BIT_OPTIONAL)) + assert(Features("08").hasInitialRoutingSync) } test("'data_loss_protect' feature") { - assert(hasFeature(hex"01", Features.OPTION_DATA_LOSS_PROTECT_MANDATORY)) - assert(hasFeature(hex"02", Features.OPTION_DATA_LOSS_PROTECT_OPTIONAL)) + assert(Features("01").hasOptionDataLossProtectMandatory) + assert(Features("02").hasOptionDataLossProtectOptional) } test("'initial_routing_sync' and 'data_loss_protect' feature") { - val features = hex"0a" - assert(areSupported(features) && hasFeature(features, OPTION_DATA_LOSS_PROTECT_OPTIONAL) && hasFeature(features, INITIAL_ROUTING_SYNC_BIT_OPTIONAL)) + val features = Features("0a") + assert(features.areSupported && features.hasOptionDataLossProtectOptional && features.hasInitialRoutingSync) } test("features compatibility") { - assert(areSupported(Protocol.writeUInt64(1l << INITIAL_ROUTING_SYNC_BIT_OPTIONAL, ByteOrder.BIG_ENDIAN))) - assert(areSupported(Protocol.writeUInt64(1L << OPTION_DATA_LOSS_PROTECT_MANDATORY, ByteOrder.BIG_ENDIAN))) - assert(areSupported(Protocol.writeUInt64(1l << OPTION_DATA_LOSS_PROTECT_OPTIONAL, ByteOrder.BIG_ENDIAN))) - assert(areSupported(hex"14") == false) - assert(areSupported(hex"0141") == false) + assert(Features(bin"1000").areSupported) + assert(Features(bin"1").areSupported) + assert(Features(bin"10").areSupported) + assert(Features(bin"10000000000000000000000000000000000000").areSupported) + assert(Features(bin"100000000000000000000000000000000000000").areSupported == false) + assert(Features(bin"10100").areSupported == false) + assert(Features(bin"101000001").areSupported == false) } } 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..20930a5a86 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.router.{Rebroadcast, RoutingSyncSpec} +import fr.acinq.eclair.wire.{ChannelCodecsSpec, Color, EncodedShortChannelIds, EncodingType, Error, IPv4, NodeAddress, NodeAnnouncement, Ping, Pong, QueryShortChannelIds, Tlv, TlvStream} import org.scalatest.{Outcome, Tag} import scodec.bits.ByteVector + import scala.concurrent.duration._ class PeerSpec extends TestkitBaseClass { @@ -43,7 +41,7 @@ class PeerSpec extends TestkitBaseClass { def ipv4FromInet4(address: InetSocketAddress) = IPv4.apply(address.getAddress.asInstanceOf[Inet4Address], address.getPort) val fakeIPAddress = NodeAddress.fromParts("1.2.3.4", 42000).get - val shortChannelIds = ChannelRangeQueriesSpec.shortChannelIds.take(100) + val shortChannelIds = RoutingSyncSpec.shortChannelIds.take(100) val fakeRoutingInfo = shortChannelIds.map(makeFakeRoutingInfo) val channels = fakeRoutingInfo.map(_._1).toList val updates = (fakeRoutingInfo.map(_._2) ++ fakeRoutingInfo.map(_._3)).toList @@ -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") @@ -320,7 +318,10 @@ class PeerSpec extends TestkitBaseClass { val probe = TestProbe() connect(remoteNodeId, authenticator, watcher, router, relayer, connection, transport, peer) - val query = wire.QueryShortChannelIds(Alice.nodeParams.chainHash, ChannelRangeQueries.encodeShortChannelIdsSingle(Seq(ShortChannelId(42000)), ChannelRangeQueries.UNCOMPRESSED_FORMAT, useGzip = false)) + val query = QueryShortChannelIds( + Alice.nodeParams.chainHash, + EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(ShortChannelId(42000))), + TlvStream(List.empty[Tlv])) // make sure that routing messages go through for (ann <- channels ++ updates) { 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/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") { 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) + } } diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/router/ChannelRangeQueriesSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/router/ChannelRangeQueriesSpec.scala index 4aa74b7999..a2a5e4535e 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/router/ChannelRangeQueriesSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/router/ChannelRangeQueriesSpec.scala @@ -16,63 +16,69 @@ package fr.acinq.eclair.router -import fr.acinq.bitcoin.Block -import fr.acinq.eclair.ShortChannelId -import fr.acinq.eclair.wire.ReplyChannelRange +import fr.acinq.eclair.randomKey +import fr.acinq.eclair.wire._ import org.scalatest.FunSuite -import scala.collection.{SortedSet, immutable} +import scala.collection.immutable.SortedMap +import scala.compat.Platform class ChannelRangeQueriesSpec extends FunSuite { - import ChannelRangeQueriesSpec._ - - test("create `reply_channel_range` messages (uncompressed format)") { - val blocks = ChannelRangeQueries.encodeShortChannelIds(400000, 20000, shortChannelIds, ChannelRangeQueries.UNCOMPRESSED_FORMAT) - val replies = blocks.map(block => ReplyChannelRange(Block.RegtestGenesisBlock.blockId, block.firstBlock, block.numBlocks, 1, block.shortChannelIds)) - var decoded = Set.empty[ShortChannelId] - replies.foreach(reply => decoded = decoded ++ ChannelRangeQueries.decodeShortChannelIds(reply.data)._2) - assert(decoded == shortChannelIds) - } - test("create `reply_channel_range` messages (ZLIB format)") { - val blocks = ChannelRangeQueries.encodeShortChannelIds(400000, 20000, shortChannelIds, ChannelRangeQueries.ZLIB_FORMAT, useGzip = false) - val replies = blocks.map(block => ReplyChannelRange(Block.RegtestGenesisBlock.blockId, block.firstBlock, block.numBlocks, 1, block.shortChannelIds)) - var decoded = Set.empty[ShortChannelId] - replies.foreach(reply => decoded = decoded ++ { - val (ChannelRangeQueries.ZLIB_FORMAT, ids, false) = ChannelRangeQueries.decodeShortChannelIds(reply.data) - ids - }) - assert(decoded == shortChannelIds) - } + test("compute flag tests") { - test("create `reply_channel_range` messages (GZIP format)") { - val blocks = ChannelRangeQueries.encodeShortChannelIds(400000, 20000, shortChannelIds, ChannelRangeQueries.ZLIB_FORMAT, useGzip = true) - val replies = blocks.map(block => ReplyChannelRange(Block.RegtestGenesisBlock.blockId, block.firstBlock, block.numBlocks, 1, block.shortChannelIds)) - var decoded = Set.empty[ShortChannelId] - replies.foreach(reply => decoded = decoded ++ { - val (ChannelRangeQueries.ZLIB_FORMAT, ids, true) = ChannelRangeQueries.decodeShortChannelIds(reply.data) - ids - }) - assert(decoded == shortChannelIds) - } + val now = Platform.currentTime / 1000 - test("create empty `reply_channel_range` message") { - val blocks = ChannelRangeQueries.encodeShortChannelIds(400000, 20000, SortedSet.empty[ShortChannelId], ChannelRangeQueries.ZLIB_FORMAT, useGzip = false) - val replies = blocks.map(block => ReplyChannelRange(Block.RegtestGenesisBlock.blockId, block.firstBlock, block.numBlocks, 1, block.shortChannelIds)) - var decoded = Set.empty[ShortChannelId] - replies.foreach(reply => decoded = decoded ++ { - val (format, ids, false) = ChannelRangeQueries.decodeShortChannelIds(reply.data) - ids - }) - assert(decoded.isEmpty) - } -} + val a = randomKey.publicKey + val b = randomKey.publicKey + val ab = RouteCalculationSpec.makeChannel(123466L, a, b) + val (ab1, uab1) = RouteCalculationSpec.makeUpdateShort(ab.shortChannelId, ab.nodeId1, ab.nodeId2, 0, 0, timestamp = now) + val (ab2, uab2) = RouteCalculationSpec.makeUpdateShort(ab.shortChannelId, ab.nodeId2, ab.nodeId1, 0, 0, timestamp = now) + + val c = randomKey.publicKey + val d = randomKey.publicKey + val cd = RouteCalculationSpec.makeChannel(451312L, c, d) + val (cd1, ucd1) = RouteCalculationSpec.makeUpdateShort(cd.shortChannelId, cd.nodeId1, cd.nodeId2, 0, 0, timestamp = now) + val (_, ucd2) = RouteCalculationSpec.makeUpdateShort(cd.shortChannelId, cd.nodeId2, cd.nodeId1, 0, 0, timestamp = now) + + val e = randomKey.publicKey + val f = randomKey.publicKey + val ef = RouteCalculationSpec.makeChannel(167514L, e, f) + + val channels = SortedMap( + ab.shortChannelId -> ab, + cd.shortChannelId -> cd + ) -object ChannelRangeQueriesSpec { - lazy val shortChannelIds: immutable.SortedSet[ShortChannelId] = (for { - block <- 400000 to 420000 - txindex <- 0 to 5 - outputIndex <- 0 to 1 - } yield ShortChannelId(block, txindex, outputIndex)).foldLeft(SortedSet.empty[ShortChannelId])(_ + _) + val updates = Map( + ab1 -> uab1, + ab2 -> uab2, + cd1 -> ucd1 + ) + + import fr.acinq.eclair.wire.QueryFlagType._ + + assert(Router.getChannelDigestInfo(channels, updates)(ab.shortChannelId) == (Timestamps(now, now), Checksums(3297511804L, 3297511804L))) + + // no extended info but we know the channel: we ask for the updates + assert(Router.computeFlag(channels, updates)(ab.shortChannelId, None, None) === (INCLUDE_CHANNEL_UPDATE_1 | INCLUDE_CHANNEL_UPDATE_2).toByte) + // same checksums, newer timestamps: we don't ask anything + assert(Router.computeFlag(channels, updates)(ab.shortChannelId, Some(Timestamps(now + 1, now + 1)), Some(Checksums(3297511804L, 3297511804L))) === 0.toByte) + // different checksums, newer timestamps: we ask for the updates + assert(Router.computeFlag(channels, updates)(ab.shortChannelId, Some(Timestamps(now + 1, now)), Some(Checksums(154654604, 3297511804L))) === INCLUDE_CHANNEL_UPDATE_1) + assert(Router.computeFlag(channels, updates)(ab.shortChannelId, Some(Timestamps(now, now + 1)), Some(Checksums(3297511804L, 45664546))) === INCLUDE_CHANNEL_UPDATE_2) + assert(Router.computeFlag(channels, updates)(ab.shortChannelId, Some(Timestamps(now + 1, now + 1)), Some(Checksums(154654604, 45664546+6))) === (INCLUDE_CHANNEL_UPDATE_1 | INCLUDE_CHANNEL_UPDATE_2).toByte) + // different checksums, older timestamps: we don't ask anything + assert(Router.computeFlag(channels, updates)(ab.shortChannelId, Some(Timestamps(now - 1, now)), Some(Checksums(154654604, 3297511804L))) === 0.toByte) + assert(Router.computeFlag(channels, updates)(ab.shortChannelId, Some(Timestamps(now, now - 1)), Some(Checksums(3297511804L, 45664546))) === 0.toByte) + assert(Router.computeFlag(channels, updates)(ab.shortChannelId, Some(Timestamps(now - 1, now - 1)), Some(Checksums(154654604, 45664546))) === 0.toByte) + + // missing channel update: we ask for it + assert(Router.computeFlag(channels, updates)(cd.shortChannelId, Some(Timestamps(now, now)), Some(Checksums(3297511804L, 3297511804L))) === INCLUDE_CHANNEL_UPDATE_2) + + // unknown channel: we ask everything + assert(Router.computeFlag(channels, updates)(ef.shortChannelId, None, None) === INCLUDE_ALL) + + } } diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/router/RouteCalculationSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/router/RouteCalculationSpec.scala index 2ff00c4946..d6698edb16 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/router/RouteCalculationSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/router/RouteCalculationSpec.scala @@ -900,12 +900,12 @@ object RouteCalculationSpec { makeUpdateShort(ShortChannelId(shortChannelId), nodeId1, nodeId2, feeBaseMsat, feeProportionalMillionth, minHtlcMsat, maxHtlcMsat, cltvDelta) } - def makeUpdateShort(shortChannelId: ShortChannelId, nodeId1: PublicKey, nodeId2: PublicKey, feeBaseMsat: Int, feeProportionalMillionth: Int, minHtlcMsat: Long = DEFAULT_AMOUNT_MSAT, maxHtlcMsat: Option[Long] = None, cltvDelta: Int = 0): (ChannelDesc, ChannelUpdate) = + def makeUpdateShort(shortChannelId: ShortChannelId, nodeId1: PublicKey, nodeId2: PublicKey, feeBaseMsat: Int, feeProportionalMillionth: Int, minHtlcMsat: Long = DEFAULT_AMOUNT_MSAT, maxHtlcMsat: Option[Long] = None, cltvDelta: Int = 0, timestamp: Long = 0): (ChannelDesc, ChannelUpdate) = ChannelDesc(shortChannelId, nodeId1, nodeId2) -> ChannelUpdate( signature = DUMMY_SIG, chainHash = Block.RegtestGenesisBlock.hash, shortChannelId = shortChannelId, - timestamp = 0L, + timestamp = timestamp, messageFlags = maxHtlcMsat match { case Some(_) => 1 case None => 0 diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/router/RouterSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/router/RouterSpec.scala index 5be5540eee..34d5478c29 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/router/RouterSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/router/RouterSpec.scala @@ -33,7 +33,6 @@ import fr.acinq.eclair.wire.QueryShortChannelIds import fr.acinq.eclair.{Globals, ShortChannelId, randomKey} import scodec.bits._ -import scala.collection.SortedSet import scala.compat.Platform import scala.concurrent.duration._ @@ -277,6 +276,6 @@ class RouterSpec extends BaseRouterSpec { val transport = TestProbe() probe.send(router, PeerRoutingMessage(transport.ref, remoteNodeId, update1)) val query = transport.expectMsgType[QueryShortChannelIds] - assert(ChannelRangeQueries.decodeShortChannelIds(query.data)._2 == SortedSet(channelId)) + assert(query.shortChannelIds.array == List(channelId)) } } diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/router/RoutingSyncSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/router/RoutingSyncSpec.scala index 1c4d851b65..9c785e2b5a 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/router/RoutingSyncSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/router/RoutingSyncSpec.scala @@ -16,82 +16,196 @@ package fr.acinq.eclair.router -import akka.actor.ActorSystem +import akka.actor.{Actor, ActorSystem, Props} import akka.testkit.{TestFSMRef, TestKit, TestProbe} -import fr.acinq.bitcoin.Block +import fr.acinq.bitcoin.Crypto.{PrivateKey, PublicKey} +import fr.acinq.bitcoin.{Block, Satoshi, Script, Transaction, TxIn, TxOut} import fr.acinq.eclair.TestConstants.{Alice, Bob} import fr.acinq.eclair._ +import fr.acinq.eclair.blockchain.{UtxoStatus, ValidateRequest, ValidateResult} import fr.acinq.eclair.crypto.TransportHandler import fr.acinq.eclair.io.Peer.PeerRoutingMessage import fr.acinq.eclair.router.Announcements.{makeChannelUpdate, makeNodeAnnouncement} import fr.acinq.eclair.router.BaseRouterSpec.channelAnnouncement +import fr.acinq.eclair.transactions.Scripts import fr.acinq.eclair.wire._ import org.scalatest.FunSuiteLike -import scala.concurrent.duration._ +import scala.collection.immutable.TreeMap +import scala.collection.{SortedSet, immutable, mutable} +import scala.compat.Platform class RoutingSyncSpec extends TestKit(ActorSystem("test")) with FunSuiteLike { - import RoutingSyncSpec.makeFakeRoutingInfo + import RoutingSyncSpec._ - val shortChannelIds = ChannelRangeQueriesSpec.shortChannelIds.take(350) - val fakeRoutingInfo = shortChannelIds.map(makeFakeRoutingInfo).map(t => t._1.shortChannelId -> t).toMap + val fakeRoutingInfo: TreeMap[ShortChannelId, (ChannelAnnouncement, ChannelUpdate, ChannelUpdate, NodeAnnouncement, NodeAnnouncement)] = RoutingSyncSpec + .shortChannelIds + .take(2345) + .foldLeft(TreeMap.empty[ShortChannelId, (ChannelAnnouncement, ChannelUpdate, ChannelUpdate, NodeAnnouncement, NodeAnnouncement)]) { + case (m, shortChannelId) => m + (shortChannelId -> makeFakeRoutingInfo(shortChannelId)) + } - test("handle channel range queries") { - val params = TestConstants.Alice.nodeParams - val router = TestFSMRef(new Router(params, TestProbe().ref)) - val transport = TestProbe() + class YesWatcher extends Actor { + override def receive: Receive = { + case ValidateRequest(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 class BasicSyncResult(ranges: Int, queries: Int, channels: Int, updates: Int) + + case class SyncResult(ranges: Seq[ReplyChannelRange], queries: Seq[QueryShortChannelIds], channels: Seq[ChannelAnnouncement], updates: Seq[ChannelUpdate]) { + def counts = BasicSyncResult(ranges.size, queries.size, channels.size, updates.size) + } + + def sync(src: TestFSMRef[State, Data, Router], tgt: TestFSMRef[State, Data, Router], extendedQueryFlags_opt: Option[QueryChannelRangeExtension]): SyncResult = { val sender = TestProbe() - sender.ignoreMsg { case _: TransportHandler.ReadAck => true } - val remoteNodeId = TestConstants.Bob.nodeParams.nodeId + val pipe = TestProbe() + pipe.ignoreMsg { + case _: TransportHandler.ReadAck => true + case _: GossipTimestampFilter => true + } + val srcId = src.underlyingActor.nodeParams.nodeId + val tgtId = tgt.underlyingActor.nodeParams.nodeId + sender.send(src, SendChannelQuery(tgtId, pipe.ref, extendedQueryFlags_opt)) + // src sends a query_channel_range to bob + val qcr = pipe.expectMsgType[QueryChannelRange] + pipe.send(tgt, PeerRoutingMessage(pipe.ref, srcId, qcr)) + // this allows us to know when the last reply_channel_range has been set + pipe.send(tgt, 'data) + // tgt answers with reply_channel_ranges + val rcrs = pipe.receiveWhile() { + case rcr: ReplyChannelRange => rcr + } + pipe.expectMsgType[Data] + rcrs.foreach(rcr => pipe.send(src, PeerRoutingMessage(pipe.ref, tgtId, rcr))) + // then src will now query announcements + var queries = Vector.empty[QueryShortChannelIds] + var channels = Vector.empty[ChannelAnnouncement] + var updates = Vector.empty[ChannelUpdate] + while (src.stateData.sync.nonEmpty) { + // for each chunk, src sends a query_short_channel_id + val query = pipe.expectMsgType[QueryShortChannelIds] + pipe.send(tgt, PeerRoutingMessage(pipe.ref, srcId, query)) + queries = queries :+ query + val announcements = pipe.receiveWhile() { + case c: ChannelAnnouncement => + channels = channels :+ c + c + case u: ChannelUpdate => + updates = updates :+ u + u + } + // tgt replies with announcements + announcements.foreach(ann => pipe.send(src, PeerRoutingMessage(pipe.ref, tgtId, ann))) + // and tgt ends this chunk with a reply_short_channel_id_end + val rscie = pipe.expectMsgType[ReplyShortChannelIdsEnd] + pipe.send(src, PeerRoutingMessage(pipe.ref, tgtId, rscie)) + } + SyncResult(rcrs, queries, channels, updates) + } - // ask router to send a channel range query - sender.send(router, SendChannelQuery(remoteNodeId, sender.ref)) - val QueryChannelRange(chainHash, firstBlockNum, numberOfBlocks) = sender.expectMsgType[QueryChannelRange] - sender.expectMsgType[GossipTimestampFilter] + test("handle channel range extended") { + val watcher = system.actorOf(Props(new YesWatcher())) + val alice = TestFSMRef(new Router(Alice.nodeParams, watcher)) + val bob = TestFSMRef(new Router(Bob.nodeParams, watcher)) + val charlieId = randomKey.publicKey + val sender = TestProbe() + val extendedQueryFlags_opt = None - // split our answer in 3 blocks - val List(block1) = ChannelRangeQueries.encodeShortChannelIds(firstBlockNum, numberOfBlocks, shortChannelIds.take(100), ChannelRangeQueries.UNCOMPRESSED_FORMAT) - val List(block2) = ChannelRangeQueries.encodeShortChannelIds(firstBlockNum, numberOfBlocks, shortChannelIds.drop(100).take(100), ChannelRangeQueries.UNCOMPRESSED_FORMAT) - val List(block3) = ChannelRangeQueries.encodeShortChannelIds(firstBlockNum, numberOfBlocks, shortChannelIds.drop(200).take(150), ChannelRangeQueries.UNCOMPRESSED_FORMAT) + // tell alice to sync with bob + assert(BasicSyncResult(ranges = 1, queries = 0, channels = 0, updates = 0) === sync(alice, bob, extendedQueryFlags_opt).counts) + awaitCond(alice.stateData.channels === bob.stateData.channels) + awaitCond(alice.stateData.updates === bob.stateData.updates) - // send first block - sender.send(router, PeerRoutingMessage(transport.ref, remoteNodeId, ReplyChannelRange(chainHash, block1.firstBlock, block1.numBlocks, 1, block1.shortChannelIds))) - // router should ask for our first block of ids - val QueryShortChannelIds(_, data1) = transport.expectMsgType[QueryShortChannelIds] - val (_, shortChannelIds1, false) = ChannelRangeQueries.decodeShortChannelIds(data1) - assert(shortChannelIds1 == shortChannelIds.take(100)) - - // send second block - sender.send(router, PeerRoutingMessage(transport.ref, remoteNodeId, ReplyChannelRange(chainHash, block2.firstBlock, block2.numBlocks, 1, block2.shortChannelIds))) - - // send the first 50 items - shortChannelIds1.take(50).foreach(id => { - val (ca, cu1, cu2, _, _) = fakeRoutingInfo(id) - sender.send(router, PeerRoutingMessage(transport.ref, remoteNodeId, ca)) - sender.send(router, PeerRoutingMessage(transport.ref, remoteNodeId, cu1)) - sender.send(router, PeerRoutingMessage(transport.ref, remoteNodeId, cu2)) - }) - - // send the last 50 items - shortChannelIds1.drop(50).foreach(id => { - val (ca, cu1, cu2, _, _) = fakeRoutingInfo(id) - sender.send(router, PeerRoutingMessage(transport.ref, remoteNodeId, ca)) - sender.send(router, PeerRoutingMessage(transport.ref, remoteNodeId, cu1)) - sender.send(router, PeerRoutingMessage(transport.ref, remoteNodeId, cu2)) - }) - - // during that time, router should not have asked for more ids, it already has a pending query ! - transport.expectNoMsg(200 millis) - - // now send our ReplyShortChannelIdsEnd message - sender.send(router, PeerRoutingMessage(transport.ref, remoteNodeId, ReplyShortChannelIdsEnd(chainHash, 1.toByte))) - - // router should ask for our second block of ids - val QueryShortChannelIds(_, data2) = transport.expectMsgType[QueryShortChannelIds] - val (_, shortChannelIds2, false) = ChannelRangeQueries.decodeShortChannelIds(data2) - assert(shortChannelIds2 == shortChannelIds.drop(100).take(100)) + // add some channels and updates to bob and resync + fakeRoutingInfo.take(40).map(_._2._1).foreach(c => sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, c))) + fakeRoutingInfo.take(40).map(_._2._2).foreach(c => sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, c))) + awaitCond(bob.stateData.channels.size === 40 && bob.stateData.updates.size === 40) + assert(BasicSyncResult(ranges = 1, queries = 1, channels = 40, updates = 40) === sync(alice, bob, extendedQueryFlags_opt).counts) + awaitCond(alice.stateData.channels === bob.stateData.channels) + awaitCond(alice.stateData.updates === bob.stateData.updates) + + // add some updates to bob and resync + fakeRoutingInfo.take(40).map(_._2._3).foreach(c => sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, c))) + awaitCond(bob.stateData.channels.size === 40 && bob.stateData.updates.size === 80) + assert(BasicSyncResult(ranges = 1, queries = 1, channels = 40, updates = 80) === sync(alice, bob, extendedQueryFlags_opt).counts) + awaitCond(alice.stateData.channels === bob.stateData.channels) + awaitCond(alice.stateData.updates === bob.stateData.updates) + + // add everything (duplicates will be ignored) + fakeRoutingInfo.values.foreach { + case (c, u1, u2, _, _) => + sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, c)) + sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, u1)) + sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, u2)) + } + awaitCond(bob.stateData.channels.size === fakeRoutingInfo.size && bob.stateData.updates.size === 2 * fakeRoutingInfo.size) + assert(BasicSyncResult(ranges = 2, queries = 24, channels = fakeRoutingInfo.size, updates = 2 * fakeRoutingInfo.size) === sync(alice, bob, extendedQueryFlags_opt).counts) + awaitCond(alice.stateData.channels === bob.stateData.channels) + awaitCond(alice.stateData.updates === bob.stateData.updates) + } + + test("handle channel range extended (extended)") { + val watcher = system.actorOf(Props(new YesWatcher())) + val alice = TestFSMRef(new Router(Alice.nodeParams, watcher)) + val bob = TestFSMRef(new Router(Bob.nodeParams, watcher)) + val charlieId = randomKey.publicKey + val sender = TestProbe() + val extendedQueryFlags_opt = Some(QueryChannelRangeExtension(QueryChannelRangeExtension.WANT_ALL)) + + // tell alice to sync with bob + assert(BasicSyncResult(ranges = 1, queries = 0, channels = 0, updates = 0) === sync(alice, bob, extendedQueryFlags_opt).counts) + awaitCond(alice.stateData.channels === bob.stateData.channels) + awaitCond(alice.stateData.updates === bob.stateData.updates) + + // add some channels and updates to bob and resync + fakeRoutingInfo.take(40).map(_._2._1).foreach(c => sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, c))) + fakeRoutingInfo.take(40).map(_._2._2).foreach(c => sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, c))) + awaitCond(bob.stateData.channels.size === 40 && bob.stateData.updates.size === 40) + assert(BasicSyncResult(ranges = 1, queries = 1, channels = 40, updates = 40) === sync(alice, bob, extendedQueryFlags_opt).counts) + awaitCond(alice.stateData.channels === bob.stateData.channels) + awaitCond(alice.stateData.updates === bob.stateData.updates) + + // add some updates to bob and resync + fakeRoutingInfo.take(40).map(_._2._3).foreach(c => sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, c))) + awaitCond(bob.stateData.channels.size === 40 && bob.stateData.updates.size === 80) + assert(BasicSyncResult(ranges = 1, queries = 1, channels = 0, updates = 40) === sync(alice, bob, extendedQueryFlags_opt).counts) + awaitCond(alice.stateData.channels === bob.stateData.channels) + awaitCond(alice.stateData.updates === bob.stateData.updates) + + // add everything (duplicates will be ignored) + fakeRoutingInfo.values.foreach { + case (c, u1, u2, _, _) => + sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, c)) + sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, u1)) + sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, u2)) + } + awaitCond(bob.stateData.channels.size === fakeRoutingInfo.size && bob.stateData.updates.size === 2 * fakeRoutingInfo.size) + assert(BasicSyncResult(ranges = 2, queries = 24, channels = fakeRoutingInfo.size - 40, updates = 2 * (fakeRoutingInfo.size - 40)) === sync(alice, bob, extendedQueryFlags_opt).counts) + awaitCond(alice.stateData.channels === bob.stateData.channels) + awaitCond(alice.stateData.updates === bob.stateData.updates) + + // bump random channel_updates + def touchUpdate(shortChannelId: Int, side: Boolean) = { + val (c, u1, u2, _, _) = fakeRoutingInfo.values.toList(shortChannelId) + makeNewerChannelUpdate(c, if (side) u1 else u2) + } + + val bumpedUpdates = (List(0, 42, 147, 153, 654, 834, 2301).map(touchUpdate(_, true)) ++ List(1, 42, 150, 200).map(touchUpdate(_, false))).toSet + bumpedUpdates.foreach(c => sender.send(bob, PeerRoutingMessage(sender.ref, charlieId, c))) + assert(BasicSyncResult(ranges = 2, queries = 2, channels = 0, updates = bumpedUpdates.size) === sync(alice, bob, extendedQueryFlags_opt).counts) + awaitCond(alice.stateData.channels === bob.stateData.channels) + awaitCond(alice.stateData.updates === bob.stateData.updates) } test("reset sync state on reconnection") { @@ -103,39 +217,87 @@ class RoutingSyncSpec extends TestKit(ActorSystem("test")) with FunSuiteLike { val remoteNodeId = TestConstants.Bob.nodeParams.nodeId // ask router to send a channel range query - sender.send(router, SendChannelQuery(remoteNodeId, sender.ref)) - val QueryChannelRange(chainHash, firstBlockNum, numberOfBlocks) = sender.expectMsgType[QueryChannelRange] + sender.send(router, SendChannelQuery(remoteNodeId, sender.ref, None)) + val QueryChannelRange(chainHash, firstBlockNum, numberOfBlocks, _) = sender.expectMsgType[QueryChannelRange] sender.expectMsgType[GossipTimestampFilter] - val List(block1) = ChannelRangeQueries.encodeShortChannelIds(firstBlockNum, numberOfBlocks, shortChannelIds.take(100), ChannelRangeQueries.UNCOMPRESSED_FORMAT) + val block1 = ReplyChannelRange(chainHash, firstBlockNum, numberOfBlocks, 1, EncodedShortChannelIds(EncodingType.UNCOMPRESSED, fakeRoutingInfo.take(100).keys.toList), None, None) // send first block - sender.send(router, PeerRoutingMessage(transport.ref, remoteNodeId, ReplyChannelRange(chainHash, block1.firstBlock, block1.numBlocks, 1, block1.shortChannelIds))) + sender.send(router, PeerRoutingMessage(transport.ref, remoteNodeId, block1)) // router should ask for our first block of ids - val QueryShortChannelIds(_, data1) = transport.expectMsgType[QueryShortChannelIds] - // router should think that it is mssing 100 channels + assert(transport.expectMsgType[QueryShortChannelIds] === QueryShortChannelIds(chainHash, block1.shortChannelIds, None)) + // router should think that it is missing 100 channels, in one request val Some(sync) = router.stateData.sync.get(remoteNodeId) - assert(sync.totalMissingCount == 100) + assert(sync.total == 1) // simulate a re-connection - sender.send(router, SendChannelQuery(remoteNodeId, sender.ref)) + sender.send(router, SendChannelQuery(remoteNodeId, sender.ref, None)) sender.expectMsgType[QueryChannelRange] sender.expectMsgType[GossipTimestampFilter] assert(router.stateData.sync.get(remoteNodeId).isEmpty) } + + test("sync progress") { + + def req = QueryShortChannelIds(Block.RegtestGenesisBlock.hash, EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(ShortChannelId(42))), None) + + val nodeidA = randomKey.publicKey + val nodeidB = randomKey.publicKey + + val (sync1, _) = Router.updateSync(Map.empty, nodeidA, List(req, req, req, req)) + assert(Router.syncProgress(sync1) == SyncProgress(0.25D)) + + val (sync2, _) = Router.updateSync(sync1, nodeidB, List(req, req, req, req, req, req, req, req, req, req, req, req)) + assert(Router.syncProgress(sync2) == SyncProgress(0.125D)) + + // let's assume we made some progress + val sync3 = sync2 + .updated(nodeidA, sync2(nodeidA).copy(pending = List(req))) + .updated(nodeidB, sync2(nodeidB).copy(pending = List(req))) + assert(Router.syncProgress(sync3) == SyncProgress(0.875D)) + } } object RoutingSyncSpec { + + lazy val shortChannelIds: immutable.SortedSet[ShortChannelId] = (for { + block <- 400000 to 420000 + txindex <- 0 to 5 + outputIndex <- 0 to 1 + } yield ShortChannelId(block, txindex, outputIndex)).foldLeft(SortedSet.empty[ShortChannelId])(_ + _) + + // this map will store private keys so that we can sign new announcements at will + val pub2priv: mutable.Map[PublicKey, PrivateKey] = mutable.HashMap.empty + + val unused = randomKey + def makeFakeRoutingInfo(shortChannelId: ShortChannelId): (ChannelAnnouncement, ChannelUpdate, ChannelUpdate, NodeAnnouncement, NodeAnnouncement) = { - val (priv_a, priv_b, priv_funding_a, priv_funding_b) = (randomKey, randomKey, randomKey, randomKey) - val channelAnn_ab = channelAnnouncement(shortChannelId, priv_a, priv_b, priv_funding_a, priv_funding_b) - val TxCoordinates(blockHeight, _, _) = ShortChannelId.coordinates(shortChannelId) - val channelUpdate_ab = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_a, priv_b.publicKey, shortChannelId, cltvExpiryDelta = 7, 0, feeBaseMsat = 766000, feeProportionalMillionths = 10, 500000000L, timestamp = blockHeight) - val channelUpdate_ba = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv_b, priv_a.publicKey, shortChannelId, cltvExpiryDelta = 7, 0, feeBaseMsat = 766000, feeProportionalMillionths = 10, 500000000L, timestamp = blockHeight) - val nodeAnnouncement_a = makeNodeAnnouncement(priv_a, "a", Color(0, 0, 0), List()) - val nodeAnnouncement_b = makeNodeAnnouncement(priv_b, "b", Color(0, 0, 0), List()) - (channelAnn_ab, channelUpdate_ab, channelUpdate_ba, nodeAnnouncement_a, nodeAnnouncement_b) + val timestamp = Platform.currentTime / 1000 + val (priv1, priv2) = { + val (priv_a, priv_b) = (randomKey, randomKey) + if (Announcements.isNode1(priv_a.publicKey, priv_b.publicKey)) (priv_a, priv_b) else (priv_b, priv_a) + } + val priv_funding1 = unused + val priv_funding2 = unused + pub2priv += (priv1.publicKey -> priv1) + pub2priv += (priv2.publicKey -> priv2) + val channelAnn_12 = channelAnnouncement(shortChannelId, priv1, priv2, priv_funding1, priv_funding2) + val channelUpdate_12 = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv1, priv2.publicKey, shortChannelId, cltvExpiryDelta = 7, 0, feeBaseMsat = 766000, feeProportionalMillionths = 10, 500000000L, timestamp = timestamp) + val channelUpdate_21 = makeChannelUpdate(Block.RegtestGenesisBlock.hash, priv2, priv1.publicKey, shortChannelId, cltvExpiryDelta = 7, 0, feeBaseMsat = 766000, feeProportionalMillionths = 10, 500000000L, timestamp = timestamp) + val nodeAnnouncement_1 = makeNodeAnnouncement(priv1, "", Color(0, 0, 0), List()) + val nodeAnnouncement_2 = makeNodeAnnouncement(priv2, "", Color(0, 0, 0), List()) + (channelAnn_12, channelUpdate_12, channelUpdate_21, nodeAnnouncement_1, nodeAnnouncement_2) + } + + def makeNewerChannelUpdate(channelAnnouncement: ChannelAnnouncement, channelUpdate: ChannelUpdate): ChannelUpdate = { + val (local, remote) = if (Announcements.isNode1(channelUpdate.channelFlags)) (channelAnnouncement.nodeId1, channelAnnouncement.nodeId2) else (channelAnnouncement.nodeId2, channelAnnouncement.nodeId1) + val priv = pub2priv(local) + makeChannelUpdate(channelUpdate.chainHash, priv, remote, channelUpdate.shortChannelId, + channelUpdate.cltvExpiryDelta, channelUpdate.htlcMinimumMsat, + channelUpdate.feeBaseMsat, channelUpdate.feeProportionalMillionths, + channelUpdate.htlcMinimumMsat, Announcements.isEnabled(channelUpdate.channelFlags), channelUpdate.timestamp + 5000) } } 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) } diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/wire/CommonCodecsSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/wire/CommonCodecsSpec.scala index f17bc45786..0e5a856f34 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/wire/CommonCodecsSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/wire/CommonCodecsSpec.scala @@ -20,8 +20,8 @@ import java.net.{Inet4Address, Inet6Address, InetAddress} import com.google.common.net.InetAddresses import fr.acinq.bitcoin.Crypto.PrivateKey -import fr.acinq.eclair.{UInt64, randomBytes32} import fr.acinq.eclair.wire.CommonCodecs._ +import fr.acinq.eclair.{UInt64, randomBytes32} import org.scalatest.FunSuite import scodec.bits.{BitVector, HexStringSyntax} diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/wire/ExtendedQueriesCodecsSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/wire/ExtendedQueriesCodecsSpec.scala new file mode 100644 index 0000000000..4797c14d1e --- /dev/null +++ b/eclair-core/src/test/scala/fr/acinq/eclair/wire/ExtendedQueriesCodecsSpec.scala @@ -0,0 +1,92 @@ +package fr.acinq.eclair.wire + +import fr.acinq.bitcoin.Block +import fr.acinq.eclair.{ShortChannelId, UInt64} +import fr.acinq.eclair.wire.LightningMessageCodecs._ +import org.scalatest.FunSuite +import scodec.bits.ByteVector + +class ExtendedQueriesCodecsSpec extends FunSuite { + test("encode query_short_channel_ids (no optional data)") { + val query_short_channel_id = QueryShortChannelIds( + Block.RegtestGenesisBlock.blockId, + EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(ShortChannelId(142), ShortChannelId(15465), ShortChannelId(4564676))), + TlvStream(List.empty[Tlv])) + + val encoded = queryShortChannelIdsCodec.encode(query_short_channel_id).require + val decoded = queryShortChannelIdsCodec.decode(encoded).require.value + assert(decoded === query_short_channel_id) + } + + test("encode query_short_channel_ids (with optional data)") { + val query_short_channel_id = QueryShortChannelIds( + Block.RegtestGenesisBlock.blockId, + EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(ShortChannelId(142), ShortChannelId(15465), ShortChannelId(4564676))), + TlvStream[Tlv](List(EncodedQueryFlags(EncodingType.UNCOMPRESSED, List(1.toByte, 2.toByte, 3.toByte, 4.toByte, 5.toByte))))) + + val encoded = queryShortChannelIdsCodec.encode(query_short_channel_id).require + val decoded = queryShortChannelIdsCodec.decode(encoded).require.value + assert(decoded === query_short_channel_id) + } + + test("encode query_short_channel_ids (with optional data including unknown data)") { + val query_short_channel_id = QueryShortChannelIds( + Block.RegtestGenesisBlock.blockId, + EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(ShortChannelId(142), ShortChannelId(15465), ShortChannelId(4564676))), + TlvStream[Tlv]( + EncodedQueryFlags(EncodingType.UNCOMPRESSED, List(1.toByte, 2.toByte, 3.toByte, 4.toByte, 5.toByte)) :: Nil, + GenericTlv(UInt64(43), ByteVector.fromValidHex("deadbeef")) :: Nil) + ) + + val encoded = queryShortChannelIdsCodec.encode(query_short_channel_id).require + val decoded = queryShortChannelIdsCodec.decode(encoded).require.value + assert(decoded === query_short_channel_id) + } + + test("encode reply_channel_range (no optional data)") { + val replyChannelRange = ReplyChannelRange( + Block.RegtestGenesisBlock.blockId, + 1, 100, + 1.toByte, + EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(ShortChannelId(142), ShortChannelId(15465), ShortChannelId(4564676))), + None, None) + + val encoded = replyChannelRangeCodec.encode(replyChannelRange).require + val decoded = replyChannelRangeCodec.decode(encoded).require.value + assert(decoded === replyChannelRange) + } + + test("encode reply_channel_range (with optional timestamps)") { + val replyChannelRange = ReplyChannelRange( + Block.RegtestGenesisBlock.blockId, + 1, 100, + 1.toByte, + EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(ShortChannelId(142), ShortChannelId(15465), ShortChannelId(4564676))), + Some(EncodedTimestamps(EncodingType.COMPRESSED_ZLIB, List(Timestamps(1, 1), Timestamps(2, 2), Timestamps(3, 3)))), + None) + + val encoded = replyChannelRangeCodec.encode(replyChannelRange).require + val decoded = replyChannelRangeCodec.decode(encoded).require.value + assert(decoded === replyChannelRange) + } + + test("encode reply_channel_range (with optional timestamps, checksums, and unknown data)") { + val replyChannelRange = ReplyChannelRange( + Block.RegtestGenesisBlock.blockId, + 1, 100, + 1.toByte, + EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(ShortChannelId(142), ShortChannelId(15465), ShortChannelId(4564676))), + TlvStream( + List( + EncodedTimestamps(EncodingType.COMPRESSED_ZLIB, List(Timestamps(1, 1), Timestamps(2, 2), Timestamps(3, 3))), + EncodedChecksums(List(Checksums(1, 1), Checksums(2, 2), Checksums(3, 3))) + ), + GenericTlv(UInt64(7), ByteVector.fromValidHex("deadbeef")) :: Nil + ) + ) + + val encoded = replyChannelRangeCodec.encode(replyChannelRange).require + val decoded = replyChannelRangeCodec.decode(encoded).require.value + assert(decoded === replyChannelRange) + } +} diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/wire/LightningMessageCodecsSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/wire/LightningMessageCodecsSpec.scala index 700b552971..92ac5d3b44 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/wire/LightningMessageCodecsSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/wire/LightningMessageCodecsSpec.scala @@ -21,9 +21,13 @@ import java.net.{Inet4Address, InetAddress} import fr.acinq.bitcoin.Crypto.{PrivateKey, PublicKey} import fr.acinq.bitcoin.{Block, ByteVector32, ByteVector64} import fr.acinq.eclair._ +import fr.acinq.eclair.api._ import fr.acinq.eclair.crypto.Sphinx import fr.acinq.eclair.router.Announcements import fr.acinq.eclair.wire.LightningMessageCodecs._ +import org.json4s.{CustomSerializer, ShortTypeHints} +import org.json4s.JsonAST.JString +import org.json4s.jackson.Serialization import org.scalatest.FunSuite import scodec.bits.{BitVector, ByteVector, HexStringSyntax} @@ -81,9 +85,12 @@ class LightningMessageCodecsSpec extends FunSuite { val channel_update = ChannelUpdate(randomBytes64, Block.RegtestGenesisBlock.hash, ShortChannelId(1), 2, 42, 0, 3, 4, 5, 6, None) val announcement_signatures = AnnouncementSignatures(randomBytes32, ShortChannelId(42), randomBytes64, randomBytes64) val gossip_timestamp_filter = GossipTimestampFilter(Block.RegtestGenesisBlock.blockId, 100000, 1500) - val query_short_channel_id = QueryShortChannelIds(Block.RegtestGenesisBlock.blockId, randomBytes(7515)) - val query_channel_range = QueryChannelRange(Block.RegtestGenesisBlock.blockId, 100000, 1500) - val reply_channel_range = ReplyChannelRange(Block.RegtestGenesisBlock.blockId, 100000, 1500, 1, randomBytes(3200)) + val query_short_channel_id = QueryShortChannelIds(Block.RegtestGenesisBlock.blockId, EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(ShortChannelId(142), ShortChannelId(15465), ShortChannelId(4564676))), None) + val query_channel_range = QueryChannelRange(Block.RegtestGenesisBlock.blockId, 100000, 1500, Some(QueryChannelRangeExtension(QueryChannelRangeExtension.WANT_ALL))) + val reply_channel_range = ReplyChannelRange(Block.RegtestGenesisBlock.blockId, 100000, 1500, 1, + EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(ShortChannelId(142), ShortChannelId(15465), ShortChannelId(4564676))), + Some(EncodedTimestamps(EncodingType.UNCOMPRESSED, List(Timestamps(1, 1), Timestamps(2, 2), Timestamps(3, 3)))), + Some(EncodedChecksums(List(Checksums(1, 1), Checksums(2, 2), Checksums(3, 3))))) val ping = Ping(100, bin(10, 1)) val pong = Pong(bin(10, 1)) val channel_reestablish = ChannelReestablish(randomBytes32, 242842L, 42L) @@ -102,6 +109,104 @@ class LightningMessageCodecsSpec extends FunSuite { } } + test("non-reg encoding type") { + val refs = Map( + hex"01050f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206001900000000000000008e0000000000003c69000000000045a6c4" -> QueryShortChannelIds(Block.RegtestGenesisBlock.blockId, EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(ShortChannelId(142), ShortChannelId(15465), ShortChannelId(4564676))), None), + hex"01050f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206001601789c636000833e08659309a65c971d0100126e02e3" -> QueryShortChannelIds(Block.RegtestGenesisBlock.blockId, EncodedShortChannelIds(EncodingType.COMPRESSED_ZLIB, List(ShortChannelId(142), ShortChannelId(15465), ShortChannelId(4564676))), None), + hex"01050f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206001900000000000000008e0000000000003c69000000000045a6c4010400010204" -> QueryShortChannelIds(Block.RegtestGenesisBlock.blockId, EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(ShortChannelId(142), ShortChannelId(15465), ShortChannelId(4564676))), Some(EncodedQueryFlags(EncodingType.UNCOMPRESSED, List(1, 2, 4)))), + hex"01050f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206001601789c636000833e08659309a65c971d0100126e02e3010c01789c6364620100000e0008" -> QueryShortChannelIds(Block.RegtestGenesisBlock.blockId, EncodedShortChannelIds(EncodingType.COMPRESSED_ZLIB, List(ShortChannelId(142), ShortChannelId(15465), ShortChannelId(4564676))), Some(EncodedQueryFlags(EncodingType.COMPRESSED_ZLIB, List(1, 2, 4)))) + ) + + refs.forall { + case (bin, obj) => + lightningMessageCodec.decode(bin.toBitVector).require.value == obj && lightningMessageCodec.encode(obj).require == bin.toBitVector + } + } + + case class TestItem(msg: Any, hex: String) + + test("test vectors") { + + val query_channel_range = QueryChannelRange(Block.RegtestGenesisBlock.blockId, 100000, 1500, None) + val query_channel_range_timestamps_checksums = QueryChannelRange(Block.RegtestGenesisBlock.blockId, 35000, 100, Some(QueryChannelRangeExtension(QueryChannelRangeExtension.WANT_ALL))) + val reply_channel_range = ReplyChannelRange(Block.RegtestGenesisBlock.blockId, 756230, 1500, 1, + EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(ShortChannelId(142), ShortChannelId(15465), ShortChannelId(4564676))), None, None) + val reply_channel_range_zlib = ReplyChannelRange(Block.RegtestGenesisBlock.blockId, 1600, 110, 1, + EncodedShortChannelIds(EncodingType.COMPRESSED_ZLIB, List(ShortChannelId(142), ShortChannelId(15465), ShortChannelId(265462))), None, None) + val reply_channel_range_timestamps_checksums = ReplyChannelRange(Block.RegtestGenesisBlock.blockId, 122334, 1500, 1, + EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(ShortChannelId(12355), ShortChannelId(489686), ShortChannelId(4645313))), + Some(EncodedTimestamps(EncodingType.UNCOMPRESSED, List(Timestamps(164545, 948165), Timestamps(489645, 4786864), Timestamps(46456, 9788415)))), + Some(EncodedChecksums(List(Checksums(1111, 2222), Checksums(3333, 4444), Checksums(5555, 6666))))) + val reply_channel_range_timestamps_checksums_zlib = ReplyChannelRange(Block.RegtestGenesisBlock.blockId, 122334, 1500, 1, + EncodedShortChannelIds(EncodingType.COMPRESSED_ZLIB, List(ShortChannelId(12355), ShortChannelId(489686), ShortChannelId(4645313))), + Some(EncodedTimestamps(EncodingType.COMPRESSED_ZLIB, List(Timestamps(164545, 948165), Timestamps(489645, 4786864), Timestamps(46456, 9788415)))), + Some(EncodedChecksums(List(Checksums(1111, 2222), Checksums(3333, 4444), Checksums(5555, 6666))))) + val query_short_channel_id = QueryShortChannelIds(Block.RegtestGenesisBlock.blockId, EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(ShortChannelId(142), ShortChannelId(15465), ShortChannelId(4564676))), None) + val query_short_channel_id_zlib = QueryShortChannelIds(Block.RegtestGenesisBlock.blockId, EncodedShortChannelIds(EncodingType.COMPRESSED_ZLIB, List(ShortChannelId(4564), ShortChannelId(178622), ShortChannelId(4564676))), None) + val query_short_channel_id_flags = QueryShortChannelIds(Block.RegtestGenesisBlock.blockId, EncodedShortChannelIds(EncodingType.UNCOMPRESSED, List(ShortChannelId(12232), ShortChannelId(15556), ShortChannelId(4564676))), Some(EncodedQueryFlags(EncodingType.COMPRESSED_ZLIB, List(1, 2, 4)))) + val query_short_channel_id_flags_zlib = QueryShortChannelIds(Block.RegtestGenesisBlock.blockId, EncodedShortChannelIds(EncodingType.COMPRESSED_ZLIB, List(ShortChannelId(14200), ShortChannelId(46645), ShortChannelId(4564676))), Some(EncodedQueryFlags(EncodingType.COMPRESSED_ZLIB, List(1, 2, 4)))) + + val refs = List( + query_channel_range, + query_channel_range_timestamps_checksums, + reply_channel_range, + reply_channel_range_zlib, + reply_channel_range_timestamps_checksums, + reply_channel_range_timestamps_checksums_zlib, + query_short_channel_id, + query_short_channel_id_zlib, + query_short_channel_id_flags, + query_short_channel_id_flags_zlib + ) + + class EncodingTypeSerializer extends CustomSerializer[EncodingType](format => ({ null }, { + case EncodingType.UNCOMPRESSED => JString("UNCOMPRESSED") + case EncodingType.COMPRESSED_ZLIB => JString("COMPRESSED_ZLIB") + })) + + class ExtendedQueryFlagsSerializer extends CustomSerializer[QueryChannelRangeExtension](format => ({ null }, { + case QueryChannelRangeExtension(flag) => + JString(((if (QueryChannelRangeExtension.wantTimestamps(flag)) List("WANT_TIMESTAMPS") else List()) ::: (if (QueryChannelRangeExtension.wantChecksums(flag)) List("WANT_CHECKSUMS") else List())) mkString(" | ")) + })) + + implicit val formats = org.json4s.DefaultFormats.withTypeHintFieldName("type") + + new EncodingTypeSerializer + + new ExtendedQueryFlagsSerializer + + new ByteVectorSerializer + + new ByteVector32Serializer + + new UInt64Serializer + + new MilliSatoshiSerializer + + new ShortChannelIdSerializer + + new StateSerializer + + new ShaChainSerializer + + new PublicKeySerializer + + new PrivateKeySerializer + + new TransactionSerializer + + new TransactionWithInputInfoSerializer + + new InetSocketAddressSerializer + + new OutPointSerializer + + new OutPointKeySerializer + + new InputInfoSerializer + + new ColorSerializer + + new RouteResponseSerializer + + new ThrowableSerializer + + new FailureMessageSerializer + + new NodeAddressSerializer + + new DirectionSerializer + + new PaymentRequestSerializer + + ShortTypeHints(List( + classOf[QueryChannelRange], + classOf[ReplyChannelRange], + classOf[QueryShortChannelIds])) + + refs.foreach { + obj => + val bin = lightningMessageCodec.encode(obj).require + println(Serialization.writePretty(TestItem(obj, bin.toHex))) + } + + } + test("encode/decode per-hop payload") { val payload = PerHopPayload(shortChannelId = ShortChannelId(42), amtToForward = 142000, outgoingCltvValue = 500000) val bin = LightningMessageCodecs.perHopPayloadCodec.encode(payload).require 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..818245a834 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 @@ -17,14 +17,14 @@ package fr.acinq.eclair.wire import fr.acinq.bitcoin.Crypto.PublicKey -import fr.acinq.eclair.{ShortChannelId, UInt64} import fr.acinq.eclair.UInt64.Conversions._ import fr.acinq.eclair.wire.CommonCodecs.{publicKey, shortchannelid, uint64, varint} import fr.acinq.eclair.wire.TlvCodecs._ +import fr.acinq.eclair.{ShortChannelId, UInt64} import org.scalatest.FunSuite +import scodec.Codec import scodec.bits.HexStringSyntax import scodec.codecs._ -import scodec.Codec /** * Created by t-bast on 20/06/2019. @@ -34,124 +34,302 @@ class TlvCodecsSpec extends FunSuite { import TlvCodecsSpec._ - test("encode/decode tlv") { + test("encode/decode truncated uint16") { 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"00", 0), + (hex"01 01", 1), + (hex"01 2a", 42), + (hex"01 ff", 255), + (hex"02 0100", 256), + (hex"02 0231", 561), + (hex"02 ffff", 65535) ) for ((bin, expected) <- testCases) { - val decoded = testTlvCodec.decode(bin.toBitVector).require.value.asInstanceOf[Tlv] + val decoded = tu16.decode(bin.bits).require.value assert(decoded === expected) - val encoded = testTlvCodec.encode(expected).require.toByteVector + + val encoded = tu16.encode(expected).require.bytes assert(encoded === bin) } } - test("decode invalid tlv") { + test("encode/decode truncated uint32") { val testCases = Seq( - hex"fd02", // type truncated - hex"fd022a", // truncated after type - hex"fd0100", // not minimally encoded type - hex"2a fd02", // length truncated - hex"2a fd0226", // truncated after length - hex"2a fe01010000", // not minimally encoded length - hex"2a fd2602 0231", // value truncated - hex"02 01 2a", // short channel id too short - hex"02 09 010101010101010101", // short channel id length too big - hex"2a ff0000000000000080" // invalid length (too big to fit inside a long) + (hex"00", 0L), + (hex"01 01", 1L), + (hex"01 2a", 42L), + (hex"01 ff", 255L), + (hex"02 0100", 256L), + (hex"02 0231", 561L), + (hex"02 ffff", 65535L), + (hex"03 010000", 65536L), + (hex"03 ffffff", 16777215L), + (hex"04 01000000", 16777216L), + (hex"04 01020304", 16909060L), + (hex"04 ffffffff", 4294967295L) ) - for (testCase <- testCases) { - assert(testTlvCodec.decode(testCase.toBitVector).isFailure) + for ((bin, expected) <- testCases) { + val decoded = tu32.decode(bin.bits).require.value + assert(decoded === expected) + + val encoded = tu32.encode(expected).require.bytes + assert(encoded === bin) + } + } + + test("encode/decode truncated uint64") { + val testCases = Seq( + (hex"00", UInt64(0)), + (hex"01 01", UInt64(1)), + (hex"01 2a", UInt64(42)), + (hex"01 ff", UInt64(255)), + (hex"02 0100", UInt64(256)), + (hex"02 0231", UInt64(561)), + (hex"02 ffff", UInt64(65535)), + (hex"03 010000", UInt64(65536)), + (hex"03 ffffff", UInt64(16777215)), + (hex"04 01000000", UInt64(16777216)), + (hex"04 01020304", UInt64(16909060)), + (hex"04 ffffffff", UInt64(4294967295L)), + (hex"05 0100000000", UInt64(4294967296L)), + (hex"05 0102030405", UInt64(4328719365L)), + (hex"05 ffffffffff", UInt64(1099511627775L)), + (hex"06 010000000000", UInt64(1099511627776L)), + (hex"06 010203040506", UInt64(1108152157446L)), + (hex"06 ffffffffffff", UInt64(281474976710655L)), + (hex"07 01000000000000", UInt64(281474976710656L)), + (hex"07 01020304050607", UInt64(283686952306183L)), + (hex"07 ffffffffffffff", UInt64(72057594037927935L)), + (hex"08 0100000000000000", UInt64(72057594037927936L)), + (hex"08 0102030405060708", UInt64(72623859790382856L)), + (hex"08 ffffffffffffffff", UInt64.MaxValue) + ) + + for ((bin, expected) <- testCases) { + val decoded = tu64.decode(bin.bits).require.value + assert(decoded === expected) + + val encoded = tu64.encode(expected).require.bytes + assert(encoded === bin) + } + } + + test("decode invalid truncated integers") { + val testCases = Seq( + (tu16, hex"01 00"), // not minimal + (tu16, hex"02 0001"), // not minimal + (tu16, hex"03 ffffff"), // length too big + (tu32, hex"01 00"), // not minimal + (tu32, hex"02 0001"), // not minimal + (tu32, hex"03 000100"), // not minimal + (tu32, hex"04 00010000"), // not minimal + (tu32, hex"05 ffffffffff"), // length too big + (tu64, hex"01 00"), // not minimal + (tu64, hex"02 0001"), // not minimal + (tu64, hex"03 000100"), // not minimal + (tu64, hex"04 00010000"), // not minimal + (tu64, hex"05 0001000000"), // not minimal + (tu64, hex"06 000100000000"), // not minimal + (tu64, hex"07 00010000000000"), // not minimal + (tu64, hex"08 0001000000000000"), // not minimal + (tu64, hex"09 ffffffffffffffffff") // length too big + ) + + for ((codec, bin) <- testCases) { + assert(codec.decode(bin.bits).isFailure, bin) + } + } + + test("encode/decode tlv stream") { + val testCases = Seq( + (hex"", TlvStream[TestTlv]()), + (hex"21 00", TlvStream[TestTlv](Nil, Seq(GenericTlv(33, hex"")))), + (hex"fd0102 00", TlvStream[TestTlv](Nil, Seq(GenericTlv(513, hex"")))), + (hex"fdfd00 00", TlvStream[TestTlv](Nil, Seq(GenericTlv(253, hex"")))), + (hex"fdff00 00", TlvStream[TestTlv](Nil, Seq(GenericTlv(255, hex"")))), + (hex"fe01000002 00", TlvStream[TestTlv](Nil, Seq(GenericTlv(33554433, hex"")))), + (hex"ff0100000000000002 00", TlvStream[TestTlv](Nil, Seq(GenericTlv(144115188075855873L, hex"")))), + (hex"01 00", TlvStream[TestTlv](TestType1(0))), + (hex"01 01 01", TlvStream[TestTlv](TestType1(1))), + (hex"01 01 2a", TlvStream[TestTlv](TestType1(42))), + (hex"01 02 0100", TlvStream[TestTlv](TestType1(256))), + (hex"01 03 010000", TlvStream[TestTlv](TestType1(65536))), + (hex"01 04 01000000", TlvStream[TestTlv](TestType1(16777216))), + (hex"01 05 0100000000", TlvStream[TestTlv](TestType1(4294967296L))), + (hex"01 06 010000000000", TlvStream[TestTlv](TestType1(1099511627776L))), + (hex"01 07 01000000000000", TlvStream[TestTlv](TestType1(281474976710656L))), + (hex"01 08 0100000000000000", TlvStream[TestTlv](TestType1(72057594037927936L))), + (hex"02 08 0000000000000226", TlvStream[TestTlv](TestType2(ShortChannelId(550)))), + (hex"03 31 023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb 0000000000000231 0000000000000451", TlvStream[TestTlv](TestType3(PublicKey(hex"023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb"), 561, 1105))), + (hex"fdfe00 02 0226", TlvStream[TestTlv](TestType254(550))), + (hex"01020231 02080000000000000451 033102eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f28368661900000000000002310000000000000451", TlvStream[TestTlv](TestType1(561), TestType2(ShortChannelId(1105)), TestType3(PublicKey(hex"02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619"), 561, 1105))), + (hex"01020231 0b020451 fdfe0002002a", TlvStream[TestTlv](Seq(TestType1(561), TestType254(42)), Seq(GenericTlv(11, hex"0451")))) + ) + + for ((bin, expected) <- testCases) { + val decoded = testTlvStreamCodec.decode(bin.bits).require.value + assert(decoded === expected) + val encoded = testTlvStreamCodec.encode(expected).require.bytes + assert(encoded === bin) } } test("decode invalid tlv stream") { val testCases = Seq( - hex"0108000000000000002a 02", // valid tlv record followed by invalid tlv record (only type, length and value are missing) - hex"02080000000000000226 0108000000000000002a", // valid tlv records but invalid ordering + // Type truncated. + hex"fd", + hex"fd01", + // Not minimally encoded type. + hex"fd0100 00", + // Missing length. + hex"fd0101", + // Length truncated. + hex"0f fd", + hex"0f fd02", + // Not minimally encoded length. + hex"0f fd0100 00", + hex"0f fe01000000 00", + // Missing value. + hex"0f fd0226", + // Value truncated. + hex"0f fd0102 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + // Unknown even type. + hex"12 00", + hex"0a 00", + hex"fd0201 00", + hex"fe02000001 00", + hex"01020101 0a0101", + hex"ff0200000000000001 00", + // Invalid TestTlv1. + hex"01 01 00", // not minimally-encoded + hex"01 02 0001", // not minimally-encoded + hex"01 03 000100", // not minimally-encoded + hex"01 04 00010000", // not minimally-encoded + hex"01 05 0001000000", // not minimally-encoded + hex"01 06 000100000000", // not minimally-encoded + hex"01 07 00010000000000", // not minimally-encoded + hex"01 08 0001000000000000", // not minimally-encoded + // Invalid TestTlv2. + hex"02 07 01010101010101", // invalid length + hex"02 09 010101010101010101", // invalid length + // Invalid TestTlv3. + hex"03 21 023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb", // invalid length + hex"03 29 023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb0000000000000001", // invalid length + hex"03 30 023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb000000000000000100000000000001", // invalid length + hex"03 32 023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb0000000000000001000000000000000001", // invalid length + // Invalid TestTlv254. + hex"fdfe00 00", // invalid length + hex"fdfe00 01 01", // invalid length + hex"fdfe00 03 010101", // invalid length + // Invalid multi-record streams. + hex"01012a 02", // valid tlv record followed by invalid tlv record (length missing) + hex"01012a 0208", // valid tlv record followed by invalid tlv record (value missing) + hex"01012a 020801010101", // valid tlv record followed by invalid tlv record (value truncated) + hex"02080000000000000226 01012a", // valid tlv records but invalid ordering + hex"1f00 0f012a", // valid tlv records but invalid ordering hex"02080000000000000231 02080000000000000451", // duplicate tlv type - hex"0108000000000000002a 2a0101", // unknown even type - hex"0a080000000000000231 0b0400000451" // valid tlv records but from different namespace + hex"01012a 0b020231 0b020451", // duplicate tlv type + hex"1f00 1f012a", // duplicate tlv type + hex"01012a 0a020231 0b020451" // valid tlv records but from different namespace ) for (testCase <- testCases) { - assert(tlvStream(testTlvCodec).decode(testCase.toBitVector).isFailure, testCase) + assert(testTlvStreamCodec.decode(testCase.bits).isFailure, testCase) } } - test("create invalid tlv stream") { - assertThrows[IllegalArgumentException](TlvStream(Seq(GenericTlv(42, hex"2a")))) // unknown even type - assertThrows[IllegalArgumentException](TlvStream(Seq(TestType1(561), TestType2(ShortChannelId(1105)), GenericTlv(42, hex"2a")))) // unknown even type - assertThrows[IllegalArgumentException](TlvStream(Seq(TestType1(561), TestType1(1105)))) // duplicate type - assertThrows[IllegalArgumentException](TlvStream(Seq(TestType2(ShortChannelId(1105)), TestType1(561)))) // invalid ordering + test("encode/decode length-prefixed tlv stream") { + val testCases = Seq( + hex"41 01020231 02080000000000000451 033102eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f28368661900000000000002310000000000000451", + hex"fd4d01 01020231 02080000000000000451 033102eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f28368661900000000000002310000000000000451 ff6543210987654321 fd0001 10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010010101010101" + ) + + for (testCase <- testCases) { + assert(lengthPrefixedTestTlvStreamCodec.encode(lengthPrefixedTestTlvStreamCodec.decode(testCase.bits).require.value).require.bytes === testCase) + } } - test("encode/decode tlv stream") { - val bin = hex"01080000000000000231 02080000000000000451 033102eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f28368661900000000000002310000000000000451" - val expected = Seq( - TestType1(561), - TestType2(ShortChannelId(1105)), - TestType3(PublicKey(hex"02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619"), 561, 1105) + test("decode invalid length-prefixed tlv stream") { + val testCases = Seq( + // Length too big. + hex"42 01020231 02080000000000000451 033102eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f28368661900000000000002310000000000000451", + // Length too short. + hex"40 01020231 02080000000000000451 033102eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f28368661900000000000002310000000000000451", + // Missing length. + hex"01020231 02080000000000000451 033102eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f28368661900000000000002310000000000000451", + // Valid length but duplicate types. + hex"14 02080000000000000231 02080000000000000451", + // Valid length but invalid ordering. + hex"0e 02080000000000000451 01020231", + // Valid length but unknown even type. + hex"02 0a 00" ) - val decoded = tlvStream(testTlvCodec).decode(bin.toBitVector).require.value - assert(decoded === TlvStream(expected)) + for (testCase <- testCases) { + assert(lengthPrefixedTestTlvStreamCodec.decode(testCase.bits).isFailure) + } + } - val encoded = tlvStream(testTlvCodec).encode(TlvStream(expected)).require.toByteVector - assert(encoded === bin) + test("encode unordered tlv stream (codec should sort appropriately)") { + val stream = TlvStream[TestTlv](Seq(TestType254(42), TestType1(42)), Seq(GenericTlv(13, hex"2a"), GenericTlv(11, hex"2b"))) + assert(testTlvStreamCodec.encode(stream).require.toByteVector === hex"01012a 0b012b 0d012a fdfe0002002a") + assert(lengthPrefixedTestTlvStreamCodec.encode(stream).require.toByteVector === hex"0f 01012a 0b012b 0d012a fdfe0002002a") } - test("encode/decode tlv stream with unknown odd type") { - val bin = hex"01080000000000000231 0b0400000451 0d02002a" - val expected = Seq( - TestType1(561), - GenericTlv(11, hex"00000451"), - TestType13(42) + test("encode invalid tlv stream") { + val testCases = Seq( + // Unknown even type. + TlvStream[TestTlv](Nil, Seq(GenericTlv(42, hex"2a"))), + TlvStream[TestTlv](Seq(TestType1(561), TestType2(ShortChannelId(1105))), Seq(GenericTlv(42, hex"2a"))), + // Duplicate type. + TlvStream[TestTlv](TestType1(561), TestType1(1105)), + TlvStream[TestTlv](Seq(TestType1(561)), Seq(GenericTlv(1, hex"0451"))) ) - val decoded = tlvStream(testTlvCodec).decode(bin.toBitVector).require.value - assert(decoded === TlvStream(expected)) - - val encoded = tlvStream(testTlvCodec).encode(TlvStream(expected)).require.toByteVector - assert(encoded === bin) + for (stream <- testCases) { + assert(testTlvStreamCodec.encode(stream).isFailure, stream) + assert(lengthPrefixedTestTlvStreamCodec.encode(stream).isFailure, stream) + } } } object TlvCodecsSpec { + // See https://github.com/lightningnetwork/lightning-rfc/blob/master/01-messaging.md#appendix-a-type-length-value-test-vectors + // @formatter:off sealed trait TestTlv extends Tlv - case class TestType1(uintValue: UInt64) extends TestTlv { override val `type` = UInt64(1) } - case class TestType2(shortChannelId: ShortChannelId) extends TestTlv { override val `type` = UInt64(2) } - case class TestType3(nodeId: PublicKey, value1: UInt64, value2: UInt64) extends TestTlv { override val `type` = UInt64(3) } - case class TestType13(intValue: Int) extends TestTlv { override val `type` = UInt64(13) } - - val testCodec1: Codec[TestType1] = (("length" | constant(hex"08")) :: ("value" | uint64)).as[TestType1] - 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) + case class TestType1(uintValue: UInt64) extends TestTlv + case class TestType2(shortChannelId: ShortChannelId) extends TestTlv + case class TestType3(nodeId: PublicKey, value1: UInt64, value2: UInt64) extends TestTlv + case class TestType254(intValue: Int) extends TestTlv + + private val testCodec1: Codec[TestType1] = ("value" | tu64).as[TestType1] + private val testCodec2: Codec[TestType2] = (("length" | constant(hex"08")) :: ("short_channel_id" | shortchannelid)).as[TestType2] + private val testCodec3: Codec[TestType3] = (("length" | constant(hex"31")) :: ("node_id" | publicKey) :: ("value_1" | uint64) :: ("value_2" | uint64)).as[TestType3] + private val testCodec254: Codec[TestType254] = (("length" | constant(hex"02")) :: ("value" | uint16)).as[TestType254] + + private val testTlvCodec = discriminated[TestTlv].by(varint) .typecase(1, testCodec1) .typecase(2, testCodec2) .typecase(3, testCodec3) - .typecase(13, testCodec13) - ) + .typecase(254, testCodec254) + + val testTlvStreamCodec = tlvStream(testTlvCodec) + val lengthPrefixedTestTlvStreamCodec = lengthPrefixedTlvStream(testTlvCodec) sealed trait OtherTlv extends Tlv - case class OtherType1(uintValue: UInt64) extends OtherTlv { override val `type` = UInt64(10) } - case class OtherType2(smallValue: Long) extends OtherTlv { override val `type` = UInt64(11) } + case class OtherType1(uintValue: UInt64) extends OtherTlv + case class OtherType2(smallValue: Long) extends OtherTlv - 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 otherCodec1: Codec[OtherType1] = ("value" | tu64).as[OtherType1] + val otherCodec2: Codec[OtherType2] = ("value" | tu32).as[OtherType2] + val otherTlvStreamCodec = tlvStream(discriminated[OtherTlv].by(varint) .typecase(10, otherCodec1) - .typecase(11, otherCodec2) - ) + .typecase(11, otherCodec2)) // @formatter:on } diff --git a/eclair-node-gui/pom.xml b/eclair-node-gui/pom.xml index a4d6c767fb..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-SNAPSHOT + 0.3.2-SNAPSHOT eclair-node-gui_2.11 diff --git a/eclair-node/pom.xml b/eclair-node/pom.xml index b51624433c..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-SNAPSHOT + 0.3.2-SNAPSHOT eclair-node_2.11 diff --git a/pom.xml b/pom.xml index eadb3b89d5..ed1e45b218 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ fr.acinq.eclair eclair_2.11 - 0.3.1-SNAPSHOT + 0.3.2-SNAPSHOT pom